1. 程式人生 > >紅黑樹的左旋和又旋

紅黑樹的左旋和又旋

今天先來用java實現紅黑色左旋和右旋。後邊再把新增、刪除給補充上。

什麼是紅黑樹?

紅黑樹是一種近似平衡的二叉查詢樹,它能夠確保任何一個節點的左右子樹的高度差不會超過二者中較低那個的一陪。具體來說,紅黑樹是滿足如下條件的二叉查詢樹(binary search tree):

  1. 每個節點要麼是紅色,要麼是黑色。
  2. 根節點必須是黑色
  3. 紅色節點不能連續(也即是,紅色節點的孩子和父親都不能是紅色)。
  4. 對於每個節點,從該點至null(樹尾端)的任何路徑,都含有相同個數的黑色節點。

在樹的結構發生改變時(插入或者刪除操作),往往會破壞上述條件3或條件4,需要通過調整使得查詢樹重新滿足紅黑樹的條件。

首先我們定義一個樹的節點

public class BTreeNode<T> {
    private  boolean color;
    T key;
    BTreeNode<T> rightNode;
    BTreeNode<T> leftNode;
    BTreeNode<T> parent;

    public boolean isColor() {
        return color;
    }

    public void setColor(boolean color) {
        this.color = color;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    public BTreeNode<T> getRightNode() {
        return rightNode;
    }

    public void setRightNode(BTreeNode<T> rightNode) {
        this.rightNode = rightNode;
    }

    public BTreeNode<T> getLeftNode() {
        return leftNode;
    }

    public void setLeftNode(BTreeNode<T> leftNode) {
        this.leftNode = leftNode;
    }

    public BTreeNode<T> getParent() {
        return parent;
    }

    public void setParent(BTreeNode<T> parent) {
        this.parent = parent;
    }
}

左旋和右旋程式碼:

package com.RBtree;

/**
 * @author zs
 * @Title: ${file_name}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018-10-2017:50
 */
public class BTTreeImpl<T> {

    private BTreeNode<T> mRoot;
    private static final boolean RED   = false;
    private static final boolean BLACK = true;
    //左旋
    private void  leftRate(BTreeNode<T> x){
       BTreeNode<T> y=x.rightNode;//獲取當前根節點的右節點
       x.rightNode=y.leftNode;   //把當前根節點的右節點設定為右節點的左節點
       if(y.rightNode!=null)     //這時候右節點已經與當前根節點斷開,所以
           y.rightNode.parent=x;  //我們判斷右節點是否為空,若不為空把他的父節點指向根節點
       if(x.parent==null){
           this.mRoot=y;            //若當前根節點為樹的根節點,那麼就設定當前樹的根節點為y節點。
       }else {
        if(x==x.parent.leftNode){   //當前根節點的父節點不為空,先判斷當前節點是為
            x.parent.leftNode=y;    //父節點的左節點還是右節點,然後對應賦值。
        }else {
            x.parent.rightNode=y;
        }
       }
       y.leftNode=x;               //右子節點成為根節點後設置左節點為x
       x.parent=y;                  //x的父節點指向y

    }
    //右旋
    private void  rightRate(BTreeNode<T> x){
        BTreeNode<T> y=x.leftNode;
       x.leftNode=y.rightNode;
       if(y.rightNode!=null){
           y.rightNode.parent=x;
       }
       if(x.parent==null){
           this.mRoot=y;
       }else {
           if(x==x.parent.leftNode){
               x.parent.leftNode=y;
           }else {
               x.parent.rightNode=y;
           }
       }
        y.rightNode=x;
        x.parent=y;

    }
}