1. 程式人生 > 實用技巧 >java實現紅黑樹

java實現紅黑樹

一、紅黑樹的介紹

紅黑樹(Red-Black Tree,簡稱R-B Tree),它一種特殊的二叉查詢樹。
紅黑樹是特殊的二叉查詢樹,意味著它滿足二叉查詢樹的特徵:任意一個節點所包含的鍵值,大於等於左孩子的鍵值,小於等於右孩子的鍵值。
除了具備該特性之外,紅黑樹還包括許多額外的資訊。

紅黑樹的每個節點上都有儲存位表示節點的顏色,顏色是紅(Red)或黑(Black)。
紅黑樹的特性:
(1) 每個節點或者是黑色,或者是紅色。
(2) 根節點是黑色。
(3) 每個葉子節點是黑色。 [注意:這裡葉子節點,是指為空的葉子節點!]
(4) 如果一個節點是紅色的,則它的子節點必須是黑色的。
(5) 從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

二、紅黑樹的

package com.binarytree;

public class RedBlackTree<T extends Comparable<T>> {
    
    
    
    
     class Node {
         T t;
         Node parent;
         Node left;
         Node right;
         Color color;
        public Node(T t, Node parent,Node left,Node right,
                Color color) {
            
super(); this.t = t; this.parent = parent; this.left = left; this.right = right; this.color = color; } public void setColor(Color color) { this.color=color; } } private enum
Color{ Red, Black, } Node root; Node nil=new Node(null,null,null,null,Color.Black); /* * 獲取祖父節點 */ public Node getGrandParent(Node node) { if(node.parent==null) { return null; } return node.parent.parent; } /* * 獲取當前節點的叔節點 */ public Node getUncle(Node node) { Node grandParent=getGrandParent(node); if(grandParent==null) { return null; } if(node.parent==grandParent.left) { return grandParent.right; }else { return grandParent.left; } } /* x * * a y * * b z */ //左旋 public Node leftRotate(Node x) { Node y=x.right; Node b=y.left; x.right=b; y.left=x; x.parent=y; if(b!=null) { b.parent=x; } return y; } /* x * * y a * * z b */ //右旋 public Node rightRotate(Node x) { Node y=x.left; Node b=y.right; x.left=b; y.right=x; x.parent=y; if(b!=null) { b.parent=x; } return y; } public void addNode(T t) { if(t!=null) { addNode(root,t); } } public void addNode(Node current,T t) { Node node=current; Node parent = null; boolean isLeft=true; while(node!=null) { if(t.compareTo(node.t)<0) { isLeft=true; parent=node; node=node.left; }else if(t.compareTo(node.t)>0) { isLeft=false; parent=node; node=node.right; } } if(node==null&&parent==null) { root=new Node(t,null,null,null,Color.Black); }else if(node==null&&parent!=null) { Node newNode=new Node(t,null,null,null,Color.Red); newNode.parent=parent; if(isLeft) { parent.left=newNode; }else { parent.right=newNode; } setBalance(newNode); } } //使紅黑樹保持平衡 public void setBalance(Node node) { Node current=node; Node grandparent; Node uncle; while(current.parent!=null&&current.parent.color==Color.Red) { grandparent=getGrandParent(current); uncle=getUncle(current); //父節點是祖父節點的左孩子L if(grandparent.left==current.parent) { //叔節點存在 且為紅 if(uncle!=null&&uncle.color==Color.Red) { uncle.color=Color.Black; current.parent.color=Color.Black; grandparent.color=Color.Red; current=grandparent; }else {//叔節點不存在或者為黑 LL //只旋轉一次 要變色 if(current.parent.left==current) { Node gpp=grandparent.parent;//祖父節點的父節點 grandparent.color=Color.Red; current.color=Color.Red; current.parent.color=Color.Black; if(gpp!=null&&gpp.left==grandparent) { gpp.left=rightRotate(grandparent); }else if(gpp!=null&&gpp.right==grandparent) { gpp.right=rightRotate(grandparent); }else { root= rightRotate(grandparent); } }else {//LR Node gpp=grandparent.parent;//祖父節點的父節點 grandparent.left=leftRotate(current.parent); //先變色在旋轉 grandparent.left.color=Color.Black; current.color=Color.Red; grandparent.color=Color.Red; if(gpp!=null&&gpp.left==grandparent) { gpp.left=rightRotate(grandparent); }else if(gpp!=null&&gpp.right==grandparent) { gpp.right=rightRotate(grandparent); }else { root=rightRotate(grandparent); } } } }else {//R //叔節點存在 且為紅 if(uncle!=null&&uncle.color==Color.Red) { uncle.color=Color.Black; current.parent.color=Color.Black; grandparent.color=Color.Red; current=grandparent; }else {//叔節點不存在或者為黑 if(current.parent.left==current) {//RL Node gpp=grandparent.parent;//祖父節點的父節點 grandparent.right=rightRotate(current.parent); //先變色在旋轉 grandparent.right.color=Color.Black; current.color=Color.Red; grandparent.color=Color.Red; if(gpp!=null&&gpp.left==grandparent) { gpp.left=leftRotate(grandparent); }else if(gpp!=null&&gpp.right==grandparent) { gpp.right=leftRotate(grandparent); }else { root= leftRotate(grandparent); } }else {//RR Node gpp=grandparent.parent;//祖父節點的父節點 grandparent.color=Color.Red; current.color=Color.Red; current.parent.color=Color.Black; if(gpp!=null&&gpp.left==grandparent) { gpp.left=leftRotate(grandparent); }else if(gpp!=null&&gpp.right==grandparent) { gpp.right=leftRotate(grandparent); }else { root= leftRotate(grandparent); } } } } } root.color=Color.Black; } public void deleteNode(T t) { if(t!=null) { root= deleteNode(root,t); } } public Node deleteNode(Node current,T t) { if(current==null) { return null; } if(t.compareTo(current.t)<0) { current.left=deleteNode(current.left,t); }else if(t.compareTo(current.t)>0) { current.right=deleteNode(current.right,t); }else { } return current; } /* * 前序遍歷 */ public void preTraversal(Node current) { if(current!=null) { System.out.println(current.t+" "+current.color); preTraversal(current.left); preTraversal(current.right); } } public static void main(String[] args) { RedBlackTree<Integer> rbt=new RedBlackTree<Integer>(); rbt.addNode(10); rbt.addNode(5); rbt.addNode(15); rbt.addNode(3); rbt.addNode(12); rbt.addNode(8); rbt.addNode(17); rbt.addNode(6); rbt.addNode(9); rbt.preTraversal(rbt.root); } }

實現