生活随笔
收集整理的這篇文章主要介紹了
2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AVL平衡調整步驟:
代碼寫的十分潦草而且沒經過測試,看個樂,我認為應該重點看一下沒有parent指針的版本,以及我認為這里重點在于理解過程。
插入結點
找到 插入節點的 的第一個 不平衡的 非父祖先結點
2.1 循環遍歷插入結點的祖先結點
2.2 在遍歷的同時判斷該結點是否平衡
2.3 平衡則更新當前結點的高度,為了下一次判斷是否平衡,不平衡則進行平衡調整
平衡則進行平衡調整
3.1 判斷三個結點的位置關系(LL,RR,LR,RL)
3.2 進行平衡
3.3 維護結點指針
如果是刪除導致的結點失衡,在afteradd里把break去掉就可以,一直往上查找是否導致了新的祖先結點失衡,反復平衡
而且無論是添加導致的失衡,還是刪除導致的失衡,修復的過程都是找到失衡結點進行旋轉,旋轉的過程也是一樣的,找兩個更高的子樹結點,判斷LL,RR,進行調整
更詳細的也可以看看別人寫的筆記
!!!
****我犯的錯誤::有沒有可能旋轉涉及的三個結點不連在一起? 不可能
有沒有可能LL RR LR RL之外的情況?? 不可能 ****
需要注意:旋轉中涉及到的三個結點分別是:第一個失衡非父祖先結點,第一個失衡非父祖先結點的左子結點或右子結點,第一個失衡非父祖先結點的左子結點或右子結點的左子結點或右子結點
也就是說,我們旋轉這個操作是針對失衡的那個祖先結點,涉及了三個連在一起的結點,而這三個結點不一定是插入結點本身也不一定是插入結點的父結點(除非插入結點和父結點就是和失衡結點連在一起的那種最簡單結構),我初學時總是覺得這三個點可能不在一起,實際上是混淆了平衡調整的目的是對失衡那個結點的調整,而不一定是對插入結點處,因為插入結點可能本身在很大一顆平衡的AVL子樹中。
所以旋轉的結點是三個相連的結點,自然只有這四種情況
#include <iostream>
#include "queue"
#include "stack"
#include <string>
#include <algorithm>
using namespace std
;
class AVLNode
{
public:int element
;int height
;AVLNode
*left
;AVLNode
*right
;AVLNode
*parent
;AVLNode(){this->element
= 0;this->left
= nullptr;this->right
= nullptr;this->parent
= nullptr;this->height
= 1;}AVLNode(int element
){this->element
= element
;this->left
= nullptr;this->right
= nullptr;this->parent
= nullptr;this->height
= 0;}
};class AVLtreeZH
{
private:int size
;public:AVLNode
*root
= nullptr;void add(int element
); void afterAdd(AVLNode
*node
); bool isBalanced(AVLNode
*node
); int balanceFactor(AVLNode
*node
); void balancing(AVLNode
*node
); AVLNode
*heigherChild(AVLNode
*node
); int getHeight(AVLNode
*node
); void rotateRight(AVLNode
*node1
); void rotateLeft(AVLNode
*node1
);
};void AVLtreeZH::afterAdd(AVLNode
*node
)
{while (node
->parent
!= nullptr){node
= node
->parent
;if (isBalanced(node
)){node
->height
= getHeight(node
); continue;}else{balancing(node
);break; }}
}void AVLtreeZH::balancing(AVLNode
*node1
)
{AVLNode
*node2
= heigherChild(node1
);AVLNode
*node3
= heigherChild(node2
);if (node2
== node1
->left
&& node3
== node2
->left
){ rotateRight(node1
);}if (node2
== node1
->left
&& node3
== node2
->right
){ rotateLeft(node2
);rotateRight(node1
);}if (node2
== node1
->right
&& node3
== node2
->right
){ rotateLeft(node1
);}if (node2
== node1
->right
&& node3
== node2
->left
){ rotateRight(node2
);rotateLeft(node1
);}
}void AVLtreeZH::rotateRight(AVLNode
*node1
)
{AVLNode
*node2
= heigherChild(node1
);AVLNode
*node3
= heigherChild(node2
);AVLNode
*noderoot
= node1
->parent
;node1
->left
= node2
->right
; node2
->right
= node1
;node1
->parent
= node2
; node2
->parent
= noderoot
;if (node1
->left
!= nullptr){node1
->left
->parent
= node1
;}if (noderoot
== nullptr){}else if (node1
== noderoot
->left
){node2
= noderoot
->left
;}else if (node1
== noderoot
->right
){node2
= noderoot
->right
;}node1
->height
= getHeight(node1
);node2
->height
= getHeight(node2
);node3
->height
= getHeight(node3
);if (noderoot
!= nullptr){noderoot
->height
= getHeight(noderoot
);}
}void AVLtreeZH::rotateLeft(AVLNode
*node1
)
{
}bool AVLtreeZH::isBalanced(AVLNode
*node
)
{int i
= balanceFactor(node
);if (i
< -1 || i
> 1){return false;}else if (-1 <= i
<= 1){return true;}
}int AVLtreeZH::getHeight(AVLNode
*node
)
{if (node
->left
->height
>= node
->right
->height
){return (node
->left
->height
+ 1);}else{return (node
->right
->height
+ 1);}
}int AVLtreeZH::balanceFactor(AVLNode
*node
)
{return getHeight(node
->left
) - getHeight(node
->right
);
}AVLNode
*AVLtreeZH::heigherChild(AVLNode
*node
)
{int leftheight
;int rightheight
;if (node
->left
== nullptr){leftheight
= 0;}if (node
->right
== nullptr){rightheight
= 0;}if (leftheight
== 0 && rightheight
== 0){return nullptr;}if (leftheight
> rightheight
){return node
->left
;}else if (leftheight
< rightheight
){return node
->right
;}
}
總結
以上是生活随笔為你收集整理的2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。