繼續討論旋轉
為了方便討論是做點記號
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的右子節點
privatep為r的左節點,x為p右節點node rr(node root)
當三個節點不處於一條直線,並均是左節點時,需要以插入的節點為旋轉軸向左側(逆時針)旋轉一次,然後向右側(順時針)旋轉一次,即先做rr旋轉再做一次ll旋轉
執行rr旋轉(參照rr旋轉規則)
使得a成為b的左子節點b代替a的位置b的左子節點成為a的右子節點
注意現在是以b為旋轉軸,所以c位置沒有發生變化
現在可以執行ll旋轉了(注意現在是以b為旋轉軸了),同ll旋轉一樣
看左邊部分
執行ll旋轉
那麼lr的**如果借助ll和rr的方法則變得非常簡單
private跟lr相關執行ll,rr旋轉node lr(node root)
root.left = rr(root.left);
return ll(root);
}
現實中旋轉後我們馬上可以得出平衡因子發生了變化,但在程式中我們必須手動對平衡因子做出改動
比如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)當r的絕對值等於2時,如果等於2說明樹的左邊加入了乙個節點,反之則是右側節點.pright.bf = 0;
當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...