java紅黑樹

紅黑樹描述

紅黑樹是一種二叉樹,樹上的節點分爲紅色和黑色兩種。經過對節點的規則約束,保證每一個節點到葉子節點的路徑不會相差兩倍。紅黑樹比較複雜,可是它在最壞的狀況下,也能保持比較高的效率。java

紅黑樹特色

  1. 每一個節點要麼是紅的,要麼是黑的
  2. 根節點必定是黑的
  3. 每一個葉子節點必定是黑的
  4. 若是一個節點時紅的,那麼他的葉節點必定是黑的
  5. 每一個節點到期子孫葉子節點的路徑上所通過的黑色節點數量一致

紅黑樹旋轉

左旋

以B和E的鏈接爲軸,將右側子節點E向上移動(逆時針旋轉)做爲父節點node

左旋圖示

左旋步驟:算法

1.節點E的父節點(即A)指向節點B的父節點(即A)spa

2.若節點E的父節點A爲空,則節點E將成爲新的root節點;若是左旋以前A的左節點爲節點B,則如今將A的左節點指向節點E;若是以前A的右節點爲節點B,則如今將A的右節點指向節點Ecode

3.將節點E的左節點指向節點Bclass

4.將節點2的父節點指向節點B效率

5.將節點B的右節點指向節點2二叉樹

6.將節點B的父節點指向節點Eim

代碼實現以下:數據

public class TreeMap{
    
    private Node root;//根節點

    private void rotateLeft(Node node){
         Node newRoot = node.right;
         newRoot.parent = node.parent;//節點node的父節點變爲節點node.right(newRoot)的父節點
         Node A = newRoot.parent;//設置newRoot的父節點爲A(即原來節點node的父節點)
         if(A == null){//若是A爲空,則表示原來node是根節點,則newRoot如今也應該是根節點
             root = newRoot;
         }else if(A.left == node){//若是A的左節點指向node,則如今A的左節點應該指向newRoot
             A.left = newRoot;
         }else if(A.right == node){//若是A的右節點指向node,則如今A的右節點應該指向newRoot
             A.right = newRoot;
         }
         node.parent = newRoot;//節點newRoot變爲節點node的父節點
         newRoot.left.parent = node;//節點newRoot的左節點的父節點指向節點node
         node.right = newRoot.left;//節點node的右節點指向節點newRoot的左節點
         newRoot.left = node;//節點newRoot的左節點指向node
    }
}

class Node{
   Node left;
   Node right;
   Node parent;
}

​右旋

以節點E和節點B的鏈接爲軸,將節點E向下移(順時針旋轉)變爲子節點

右旋

1.節點B的父節點(即節點A)指向節點E的父節點(即節點A)

2.若發現當前B父節點A爲空,則節點B將成爲新的root節點;若是節點A的左節點以前爲節點E,則如今A的左節點指向節點B;若是A的右節點以前爲節點E,則如今A的右節點指向節點B

3.節點2的父節點指向節點E

4.節點E的左節點指向節點2

5.節點B的右節點指向節點E

6.節點E的父節點指向節點B

代碼實現以下:

public class TreeMap{

   private Node root;//根節點

   private void rotateRight(Node node){
        Node oldRoot = node.parent;
        node.parent = oldRoot.parent;//節點node的父節點指向節點node.parent(oldRoot)的父節點
        Node A = node.parent;//設置node的父節點爲節點A
        if(A == null){//若是原來oldRoot是根節點,那麼如今node也應該是根節點
           root = node;
        }else if(A.left == oldRoot){//若是原來A的左節點是oldRoot,那麼如今A的左節點應該是node
           A.left = node;
        }else if(A.right == oldRoot){//若是原來A的右節點時oldRoot,那麼如今A的右節點應該是node
           A.right = node;
        }
        oldRoot.left = node.right;//節點oldRoot的左節點指向node的右節點
        node.right.parent = oldRoot;//節點node右節點的父節點指向oldRoot
        node.right = oldRoot;//節點node的右節點指向節點oldRoot
        oldRoot.parent = node;//節點oldRoot的父節點指向node
   }

}

class Node{
    Node left;
    Node right;
    Node parent;
}

紅黑樹操做

插入

注意事項:

1.新插入的節點,一開始是沒有顏色的,可是因爲紅黑要求每一個節點都應該有顏色,因此在插入後要給節點塗色。顏色只有兩種——黑色和紅色。若是選擇黑色的話,因爲紅黑要求任意節點往下的路徑長度(黑色節點的數量)一致,會形成新插入節點的父節點(以及再往上的節點)到下面節點的路徑長度不一樣(不平衡),這時候就須要進行路徑的調整;若是選擇紅色的話,因爲紅色節點不計入路徑長度,那麼無論插入哪裏,路徑都是不會變化的。固然紅色節點在紅黑數據也有限制——紅色節點下面的子節點必定是黑色,因此遇到插入節點的父節點也是紅色的時候,也須要進行調整。二者相比較的話,選擇黑色是必定要調整的,選擇紅色的是有可能須要調整,因此選擇紅色會更加划算一些。在紅黑樹的調整算法中,新插入節點都會選擇紅色的。

2.新插入節點會經過比較算法,最終成爲某個節點的葉子節點(沒有子節點),因此在調整時不須要考慮新插入節點的子節點狀況

插入的幾種狀況:

1.新插入節點的父節點爲黑色

在這種狀況下新插入的節點對樹是沒有影響的,由於沒有違反紅黑樹的規則。

2.新插入節點的父節點爲紅色

在這種狀況下因爲新插入節點是紅色的,致使違反了紅黑的規則。須要對紅黑樹進行調整。

刪除

相關文章
相關標籤/搜索