平衡二叉樹 AVL 實現 2

2021-06-20 16:21:48 字數 3010 閱讀 3093

繼續討論旋轉

為了方便討論是做點記號

x為插入的節點p為旋轉軸(p有時候為x的父節點如ll,rr旋轉;p有時候也為x,如lr,rl旋轉)r為平衡因子絕對值=2的節點

看下面四種情況

當三個節點處於一條直線,並均是左節點時,需要以中間的節點為旋轉軸向右側(順時針)旋轉一次

使得c成為b的右子節點

b代替c的位置

b的右子節點成為c的左子節點

private 

node ll(node root)

當三個節點處於一條直線,並均是左節點時,需要以中間的節點為旋轉軸向左側(逆時針)旋轉一次

使得a成為b的左子節點

b代替a的位置

b的左子節點成為a的右子節點

private 

node rr(node root)

p為r的左節點,x為p右節點 

當三個節點處於一條直線,並均是左節點時,需要以插入的節點為旋轉軸向左側(逆時針)旋轉一次,然後向右側(順時針)旋轉一次,即先做rr旋轉再做一次ll旋轉

執行rr旋轉(參照rr旋轉規則)

使得a成為b的左子節點b代替a的位置b的左子節點成為a的右子節點

注意現在是以b為旋轉軸,所以c位置沒有發生變化

現在可以執行ll旋轉了(注意現在是以b為旋轉軸了),同ll旋轉一樣 

看左邊部分

執行ll旋轉

那麼lr的**如果借助ll和rr的方法則變得非常簡單

private 

node lr(node root)

root.left = rr(root.left);

return ll(root);

}

跟lr相關執行ll,rr旋轉

現實中旋轉後我們馬上可以得出平衡因子發生了變化,但在程式中我們必須手動對平衡因子做出改動

比如ll旋轉前

rh(r的平衡因子)=2

ph=1

x=0

旋轉後rh=0

ph=0

x=0

ll

即當p的平衡因子為1時

if (rootnext.bf == 1)

rr即當p的平衡因子為-1時

if (rootnext.bf == -1)

比如lr旋轉

將ll和rr的**合併在一起

private 

node lr(node root)

上面的**讓人看起來思路非常的清晰,但由於是程式,所以可以簡化

rootleft就是pright

root.left不要賦值兩次

以下是改進

private 

node lr(node root)

有三種情景 

1.p的平衡因子為0

如下圖 

r的平衡因子變為0,p的父節點平衡因子變為0,自身平衡因子變為0

2.p的平衡因子為-1

r的平衡因子變為-1,p的父節點平衡因子變為0,自身平衡因子變為0

3.p的平衡因子為1

r的平衡因子變為0,p的父節點平衡因子變為1,自身平衡因子變為0

switch (pright.bf) 

pright.bf = 0;

當r的絕對值等於2時,如果等於2說明樹的左邊加入了乙個節點,反之則是右側節點.

當r==2時,則檢查r的左側節點的平衡因子,有兩種情況1或-1,如果是1的話,則ll旋轉,如果是-1的話則lr旋轉

反之當r==-2時,情況則剛好相反

private bool rotatesubtree(int bf)

else if (leftbf == 1)

}if (bf == -2)

else if (rightbf == -1)}}

話題全是緊扣著旋轉和平衡因子,還未完...

平衡二叉樹 AVL

平衡二叉樹在查詢中經常用到。由於平衡二叉樹是一種平衡的二叉排序樹,所以其建立方法必須要遵守二叉排序樹的規則,即每個新插入的節點是乙個葉子節點。它左右子樹高度差不超過1,並且要求左右子樹也是平衡二叉樹,並且左子樹的節點最大值小於根節點,右子樹節點最小值大於根節點。1 高度為log n 2 平均查詢長度...

平衡二叉樹(AVL樹)

左右子樹高度之差的絕對值不超過1,左右子樹高度之差稱為該結點的平衡因子。通過對樹的結構進行調整,使樹的高度在每次插入結束後仍能保持o logn 的級別。引入變數height來記錄高度struct node 新建乙個結點 1.申請變數空間 2 初始結點權值,高度 1 3 初始左右孩子為空 4 返回新建...

平衡二叉樹 AVL 實現(3)

現象1 注意 q是30,而不是20,因為刪除了25,節點會移動,以下現象均遵循此規律 現象2 現象3 現象1和現象2比較簡單,不需要平衡化處理,現象3則比較複雜.先討論現象1和2 先找到節點,然後刪除節點 private node findnode int value if value node.d...