數據結構之AVL樹(平衡二叉樹)

什麼叫AVL樹 平衡二叉樹?

說到這個問題我們先說說二叉排序樹 它也叫二叉搜索樹,它解決數組和鏈表集合遍歷和插入所有優勢。但是假如我們是一個這樣的樹你覺得它的效率還會很高嗎?
在這裏插入圖片描述
如上圖中 這樣一棵搜索它的效率顯然不高,因爲除了7 其他的幾個數字就類似一個鏈表。就因爲這樣的情況,所以平衡二叉樹就誕生了,它是爲了解決極限情況下,樹的搜索效率低下的問題。
那麼什麼樣的樹才叫平衡二叉樹呢?
作爲一個平衡二叉樹必須滿足下面兩個條件:

  1. 它必須是二叉查找樹;
  2. 每個節點的左子樹和右子樹的高度差至多爲1。

在這裏插入圖片描述
看看上面四個樹,那些滿足平衡二叉樹呢?
左上圖:58 和 88 不滿足左右子樹高度最大不超過1
右上圖:全部滿足
左下圖:58不滿足
右下圖:全部滿足

平衡因子 和 最小不平衡子樹

在這裏插入圖片描述
**平衡因子 :**將二叉樹上節點的左子樹高度減去右子樹高度的值稱爲該節點的平衡因子BF
如上4號圖中,我們生成了一個平衡二叉樹,那麼它每個節點的平衡因子是多少呢?
答案是所有節點平衡因子等於0
那麼在沒有轉換成平衡二叉樹之前呢?
1的平衡因子是0
2的平衡因子是1
3的平衡因子是2
4的平衡因子是3
5的平衡因子是4
6的平衡因子是4
7的平衡因子是0
最小不平衡子樹: 距離插入節點最近的,且平衡因子的絕對值大於1的節點爲根的子樹
如上圖中 1 2 3號圖中的 虛線方框中的 子樹, 就稱之爲 最小不平衡子樹

旋轉建平衡二叉樹

左旋 右旋操作

在這裏插入圖片描述

左旋規律就是 目標節點(X)的右子樹節點(Y)的左子樹(β) 要作爲目標節點(X)右子節點樹
在這裏插入圖片描述
右旋規律是把目標節點(Y)的左子樹(X)的右子樹節點(β)移到目標節點(Y)的左子樹節點上
注意: 上面的左旋和右旋規則,非常重要,它是平衡二叉樹 進行建樹的思路基礎。

平衡操作

當一個樹的節點左邊或者右邊出現最小不平衡子樹時,我們需要對這個最小不平衡子樹進行左旋 右旋或者 左旋加右旋操作使得樹最後成爲平衡二叉樹。

左平衡操作

即結點t的不平衡是因爲左子樹過深

  1. 如果新的結點插入到t的左孩子的左子樹中,則直接進行右旋操作即可
    在這裏插入圖片描述
    注意發現規律,t節點右旋,所以t節點的左子樹的右節點 被移到了 目標節點的左邊。

  2. 如果新的結點插入到t的左孩子的右子樹中,則需要進行分情況討論

    • 情況a: 當t的左孩子的右子樹根節點的balance = RIGHT_HIGH
      在這裏插入圖片描述
      同樣的規律,第二步旋轉中的 t節點右旋,所以t節點的左子樹的右節點 被移到了 目標節點的左邊。

    • 情況b:當t的左孩子的右子樹根節點的balance = LEFT_HIGH
      在這裏插入圖片描述
      左旋規律 tl左旋,所以他的右子節點的 左子樹 5 要被移到目標節點 tl 的右子樹上

右平衡操作

即結點t的不平衡是因爲右子樹過深

  1. 如果新的結點插入到t的右孩子的右子樹中,則直接進行左旋操作即可
    在這裏插入圖片描述
    對t進行左旋所以目標節點t的右子節點的左子樹 trl 在旋轉完成以後,會被移到 目標節點t 的右子節點上
  2. 如果新的結點插入到t的右孩子的左子樹中,則需要進行分情況討論
    • 情況a:當t的右孩子的左子樹根節點的balance = LEFT_HIGH
      在這裏插入圖片描述
      同樣的規律,在第二步旋轉中, 對目標節點 t進行左旋,我們需要把 t 的右子節點的左子樹 移到t的右節點上。
    • 情況b:當t的右孩子的左子樹根節點的balance = RIGHT_HIGH
      在這裏插入圖片描述
      對目標節點 tr進行右旋 ,我們需要把目標節點tr 的左子節點的右子樹,移到目標節點tr 的左子節點上。

綜上我們在新建樹過程中 所有出現最小不平衡子樹情況時,需要進行的旋轉操作。 同時我們也需要更改對應的節點上的平衡因子的值。 最終我們就完成了一個 平衡二叉樹的建樹操作。

問題

平衡二叉樹可以把搜索速度效率做到最好,但是在增加或者刪除節點時,隨時都可能改變整個樹的結構,需要便隨着大量的左旋 右旋操作,重新構成一個平衡二叉樹。 這樣大的計算量並不是我們想要的。 這個時候紅黑樹就出現了,他是爲了解決平衡二叉樹的這個問題誕生的。 降低一小部分搜索效率,但是建樹難度卻大大提高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章