1. 程式人生 > >平衡二叉樹實現-刪除

平衡二叉樹實現-刪除

來源http://www.cnblogs.com/Clingingboy/archive/2010/10/09/1846865.html

AVL樹節點的刪除規則

image

三種現象

現象1

image

注意:q是30,而不是20,因為刪除了25,節點會移動,以下現象均遵循此規律

現象2

image

現象3

image

現象1和現象2比較簡單,不需要平衡化處理,現象3則比較複雜.先討論現象1和2

現象1刪除步驟

先找到節點,然後刪除節點

private Node FindNode(int value)
     {
         currentIndex = -1;
         Node node = _head;
         while 
(node != null) { path[++currentIndex] = node; if (value == node.Data) { return node; } if (value < node.Data) { node = node.Left; } else { node = node.Right; } } return null
; } public bool Remove(int value) { var node = FindNode(value); if (node != null) { RemoveNode(node); return true; } return false; }

其刪除節點的子節點<2個,即只有左節點或者右節點或者沒節點三種可能

  1. 如果刪除的是右節點,那麼該刪除節點的子節點(如果有的話)將會代替該節點,反之也則替換左節點
  2. 代替的節點不是左節點就是右節點(只會是其中一個,若是兩個子節點的情況則另外考慮)
var tmp = node.Left;
if (tmp == null) {
    tmp = node.Right;
}
if (currentIndex > 0)
{
    if (path[currentIndex - 1].Left == node)
    {   path[currentIndex - 1].Left = tmp;
    }
    else
    {   path[currentIndex - 1].Right = tmp;
    }
}
else  {
    _head = tmp;
}

現象2刪除步驟

即該節點的平衡因子為0,說明其左子樹和右子樹的高度是相同的

刪除該節點後,其左節點代替父節點

但程式的做法沒有我們看到這麼簡單 

將左節點的值賦給父節點,然後將父節點的左節點以其原有左節點的左節點進行替換(即將15的值換成12,將15的左子節點換成12的左子節點,由於12沒有左子節點,所以12的左子節點為空),程式如下

private void RemoveNode(Node node)
{
    Node tmp = null;
    if (node.Left != null && node.Right != null)
    {
        tmp = node.Left; 
        node.Data = tmp.Data;
        node.Left = tmp.Left;
      
    }
}

現象3刪除步驟


現象3和現象2方式前期處理方式相同,但是由於其左子樹和右子樹的高度不同導致了平衡因子出現2或-2的情況,後期還要進行處理,即是對於平衡因子的處理

平衡因子的處理

還是一樣,當刪除左節點時(父節點和某些祖父節點的)平衡因子-1,反之則+1

  1. 現象1則+1
  2. 現象2則-1
  3. 現象3則是父和祖父均-1

當平衡因子絕對值變成2了,則進行旋轉

image