生活随笔
收集整理的這篇文章主要介紹了
2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
AVL平衡調(diào)整步驟:
代碼寫(xiě)的十分潦草而且沒(méi)經(jīng)過(guò)測(cè)試,看個(gè)樂(lè),我認(rèn)為應(yīng)該重點(diǎn)看一下沒(méi)有parent指針的版本,以及我認(rèn)為這里重點(diǎn)在于理解過(guò)程。
插入結(jié)點(diǎn)
找到 插入節(jié)點(diǎn)的 的第一個(gè) 不平衡的 非父祖先結(jié)點(diǎn)
2.1 循環(huán)遍歷插入結(jié)點(diǎn)的祖先結(jié)點(diǎn)
2.2 在遍歷的同時(shí)判斷該結(jié)點(diǎn)是否平衡
2.3 平衡則更新當(dāng)前結(jié)點(diǎn)的高度,為了下一次判斷是否平衡,不平衡則進(jìn)行平衡調(diào)整
平衡則進(jìn)行平衡調(diào)整
3.1 判斷三個(gè)結(jié)點(diǎn)的位置關(guān)系(LL,RR,LR,RL)
3.2 進(jìn)行平衡
3.3 維護(hù)結(jié)點(diǎn)指針
如果是刪除導(dǎo)致的結(jié)點(diǎn)失衡,在afteradd里把break去掉就可以,一直往上查找是否導(dǎo)致了新的祖先結(jié)點(diǎn)失衡,反復(fù)平衡
而且無(wú)論是添加導(dǎo)致的失衡,還是刪除導(dǎo)致的失衡,修復(fù)的過(guò)程都是找到失衡結(jié)點(diǎn)進(jìn)行旋轉(zhuǎn),旋轉(zhuǎn)的過(guò)程也是一樣的,找兩個(gè)更高的子樹(shù)結(jié)點(diǎn),判斷LL,RR,進(jìn)行調(diào)整
更詳細(xì)的也可以看看別人寫(xiě)的筆記
!!!
****我犯的錯(cuò)誤::有沒(méi)有可能旋轉(zhuǎn)涉及的三個(gè)結(jié)點(diǎn)不連在一起? 不可能
有沒(méi)有可能LL RR LR RL之外的情況?? 不可能 ****
需要注意:旋轉(zhuǎn)中涉及到的三個(gè)結(jié)點(diǎn)分別是:第一個(gè)失衡非父祖先結(jié)點(diǎn),第一個(gè)失衡非父祖先結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn),第一個(gè)失衡非父祖先結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn)
也就是說(shuō),我們旋轉(zhuǎn)這個(gè)操作是針對(duì)失衡的那個(gè)祖先結(jié)點(diǎn),涉及了三個(gè)連在一起的結(jié)點(diǎn),而這三個(gè)結(jié)點(diǎn)不一定是插入結(jié)點(diǎn)本身也不一定是插入結(jié)點(diǎn)的父結(jié)點(diǎn)(除非插入結(jié)點(diǎn)和父結(jié)點(diǎn)就是和失衡結(jié)點(diǎn)連在一起的那種最簡(jiǎn)單結(jié)構(gòu)),我初學(xué)時(shí)總是覺(jué)得這三個(gè)點(diǎn)可能不在一起,實(shí)際上是混淆了平衡調(diào)整的目的是對(duì)失衡那個(gè)結(jié)點(diǎn)的調(diào)整,而不一定是對(duì)插入結(jié)點(diǎn)處,因?yàn)椴迦虢Y(jié)點(diǎn)可能本身在很大一顆平衡的AVL子樹(shù)中。
所以旋轉(zhuǎn)的結(jié)點(diǎn)是三個(gè)相連的結(jié)點(diǎn),自然只有這四種情況
#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
;}
}
總結(jié)
以上是生活随笔為你收集整理的2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。