Java实现红黑树的完整代码

Java实现红黑树的完整代码

话不多说直接上代码。(至于思路当然我不会告诉你我是懒得写,,,)

package javaDataStructure;

import java.util.LinkedList;
import java.util.Queue;

class TreeNode{
	public int value;
	public char colorRB='r';
	
	public TreeNode parent=null;
	public TreeNode left=null;
	public TreeNode right=null;
	
	public TreeNode(int value) {
		this.value=value;
	}
}

 *   (存放 int 型数据)常见操作:增加,删除,查找,https://www.jianshu.com/p/e136ec79235c
public class redBlackTree {
	
//	public static void main(String[] args) {
//		System.out.println("I am OK!");
//		TreeNode ceshi=new TreeNode(1);
//		ceshi.colorRB='b';
//		System.out.println(ceshi.colorRB);
//	}
	
	private TreeNode root;
	
	private int SIZE=0;
	public int size() {
		return this.SIZE;
	}
	
	private int TREEDEPTH=0;
	public int treeDepth(){
		return this.TREEDEPTH;
	}
	
	 * 查找指定数据
	public boolean findData(int value) {
		if(this.root==null)return false;
		
		if(findTargetNode(this.root, value)==null) {
			return true;
		}else {
			return false;
		}
	}
	
	 * only for testing
//	public int zhongXuVisit() {
//		if(this.root==null) {
//			System.out.println("(zhongXuVisit)The tree is null.");
//			return 0;
//		}
//		int result=zXbianli(this.root);
//		//System.out.println("The real sum is "+ result );
//		return result;
//	}
//	private int zXbianli(TreeNode root) {
//		int sum=1;
//		if(root.left!=null)sum+=zXbianli(root.left);
//		if(root.right!=null)sum+=zXbianli(root.right);
//		return sum;
//	}
	
	 * Visiting all tree node from top to bottom by queue, and don't return.
	public void visitAllNode() {
		if(this.root==null) {
			System.out.println("(visitAllNode)The tree is null.");
			return;
		}
		
		Queue<TreeNode> queueTree=new LinkedList<TreeNode>();
		int thisFloorSum=1;
		int nextFloorSum=0;

		queueTree.add(root);
		while (!queueTree.isEmpty()) {
			TreeNode tempNode=queueTree.poll();
			thisFloorSum--;
			
			if(tempNode.left!=null) {
				queueTree.add(tempNode.left);
				nextFloorSum++;
			}
			if (tempNode.right!=null) {
				queueTree.add(tempNode.right);
				nextFloorSum++;
			}
			System.out.print(tempNode.value+""+tempNode.colorRB+" ");
			
			if(thisFloorSum==0) {
				thisFloorSum=nextFloorSum;
				nextFloorSum=0;
				System.out.println();
			}
		}
	}
	
	 * 将节点增加到该树中,已经存在的将不会被添加
	public void add(int value) {
		
		TreeNode addNode=new TreeNode(value);
		
		if(this.root==null) {
			this.root=addNode;
			resetTreeInformation(true);
			return;
		}

		TreeNode targetNode=null;
		targetNode=findTargetNode(this.root, value);

		if(targetNode==null) {return;}
		if(value < targetNode.value) {
			targetNode.left=addNode;
		}else {
			targetNode.right=addNode;
		}
		addNode.parent=targetNode;        //设置增加节点的父节点

		balance_RB_Tree(addNode);         // 当加入新节点后,重新平衡红黑树
		
		resetTreeInformation(true);
		
	}
	
	 *  Atfer changing this tree, it reset the information of this tree, such as the root, size, depth.
	private void resetTreeInformation(boolean sizeIsPlus) {
		this.root=findRootNode(this.root);                              // 当所指节点不是跟节点时,重新找回根节点
		this.root.colorRB='b';
		this.TREEDEPTH=findTreeDepth(this.root);
		if(sizeIsPlus) {
			this.SIZE++;
		}else {
			this.SIZE--;
		}
	}
	
	private TreeNode findRootNode(TreeNode nodeIndex) {
		return nodeIndex.parent==null?nodeIndex:findRootNode(nodeIndex.parent);
	}
	
	 * finding the depth of tree. 
	private int findTreeDepth(TreeNode root) {
		if(root==null)return 0;
		
		int leftDepth=findTreeDepth(root.left);
		int rightDepth=findTreeDepth(root.right);
		
		return 1+(leftDepth>rightDepth?leftDepth:rightDepth);
	}
	
	private TreeNode findTargetNode(TreeNode nodeIndex, int value) {
		
		if( value < nodeIndex.value && nodeIndex.left!=null) return findTargetNode(nodeIndex.left,value);
		
		if( nodeIndex.value == value ) return null;
		
		if( nodeIndex.value < value && nodeIndex.right!=null) return findTargetNode(nodeIndex.right,value);
		
		return nodeIndex;
	}
	
	private void balance_RB_Tree(TreeNode nodeIndex) {
		
		if(nodeIndex==null)return;
		
		if(nodeIndex.parent==null)return;         // 如果当前节点是红节点且为根节点(即没有父节点),退出,递归平衡时会遇到
		
		if(nodeIndex.parent.colorRB=='b')return;  // 如果父节点的颜色是黑色,则不改变树的当前节点颜色
		
		// 此时当前节点的父节点为红色,一定有祖父,因为在插入之前即为红黑树
		if(nodeIndex.parent.parent.right==null) {                    // 右边叔叔节点不存现在,父节点在祖父节点的左边
			if ( nodeIndex.value< nodeIndex.parent.value) {          // 当前节点在父节点的左边,进行右旋转
				rotateRight(nodeIndex.parent.parent);           
			}else {                                                  // 当前节点在父节点的右边,先左旋转,再右旋转
				rotateLeft(nodeIndex.parent);            
				rotateRight(nodeIndex.parent);            
			}
			return;
		}
		
		if(nodeIndex.parent.parent.left==null) {                     // 左边叔叔节点不存现在,父节点在祖父节点的右边
			if (nodeIndex.parent.value < nodeIndex.value) {          // 当前节点在父节点的右边,进行左旋转
				rotateLeft(nodeIndex.parent.parent);           
			}else {                                                  // 当前节点在父节点的左边,先右旋转,再左旋转
				rotateRight(nodeIndex.parent);            
				rotateLeft(nodeIndex.parent);            
			}
			return;
		}
		
		if(nodeIndex.parent.parent.right.colorRB=='b') {             // 右边叔叔节点存在且为黑,和不存在一样处理
			if ( nodeIndex.value< nodeIndex.parent.value) {         
				rotateRight(nodeIndex.parent.parent);           
			}else {                                                
				rotateLeft(nodeIndex.parent);            
				rotateRight(nodeIndex.parent);            
			}
			return;
		}
		
		if(nodeIndex.parent.parent.left.colorRB=='b') {
			if ( nodeIndex.parent.value < nodeIndex.value) {          // 左边叔叔节点存在且为黑,和不存在一样处理
				rotateLeft(nodeIndex.parent.parent);           
			}else {                                                 
				rotateRight(nodeIndex.parent);            
				rotateLeft(nodeIndex.parent);            
			}
			return;
		}
		
		if( nodeIndex.parent.parent.left.colorRB=='r' && nodeIndex.parent.parent.right.colorRB=='r') {
			nodeIndex.parent.parent.left.colorRB = 'b';
			nodeIndex.parent.parent.right.colorRB = 'b';
			nodeIndex.parent.parent.colorRB = 'r';
			balance_RB_Tree(nodeIndex.parent.parent);
			return;
		}

	}
	
	private void rotateRight(TreeNode nodeIndex) {
		TreeNode PP=nodeIndex;
		TreeNode P=nodeIndex.left;
		
		if(PP.parent==null) {	
			this.root=P;
		}else if(PP.value<PP.parent.value) {
			PP.parent.left=P;
		}else {
			PP.parent.right=P;
		}
		
		P.parent=PP.parent;
		PP.left=P.right;
		if(PP.left!=null)PP.left.parent=PP;
		P.right=PP;
		PP.parent=P;
		
		P.colorRB='b';
		PP.colorRB='r';
	}
	
	private void rotateLeft(TreeNode nodeIndex) {
		TreeNode PP=nodeIndex;
		TreeNode P=nodeIndex.right;
		
		if(nodeIndex.parent==null) {
			this.root=P;
		}else if(PP.value<PP.parent.value){
			PP.parent.left=P;
		}else {
			PP.parent.right=P;
		}
		
		P.parent=PP.parent;
		PP.right=P.left;
		if(PP.right!=null)PP.right.parent=PP;
		P.left=PP;
		PP.parent=P;
		
		P.colorRB='b';
		PP.colorRB='r';
	}
	
	 * 将目标节点从树中删除
	public void remove(int value) {

		if(this.root==null) return;                                // 如果树为空,不做任何删除操作

		TreeNode removeNode=findRemoveTargetNode(this.root, value);
		
		if(removeNode!=null) {

			// 找直接后继代替节点,使之只出现删除末端节点的情形     
			TreeNode replaceNode=removeNode;     
			if(removeNode.right!=null) {                            // 找到 后继 替代节点 
				replaceNode=removeNode.right;                       // 如果有右子树,则 后继 代替节点即为右子树中的最左
				while(replaceNode.left!=null)replaceNode=replaceNode.left;
			}
			
			if(replaceNode.left!=null) {                            // 如果此时还有左子节点,那一定为红的  “叶子型” 节点
				removeNode.value=removeNode.left.value;             // 此时replaceNode == removeNode
				removeNode.left=null;
				resetTreeInformation(false);
				return;
			}
			
			if(replaceNode.colorRB=='r') {                          // 此时如果为末端 红节点直接删除,不用平衡
				removeNode.value=replaceNode.value;
				if(replaceNode.value<replaceNode.parent.value) {
					replaceNode.parent.left=null;
				}else {
					replaceNode.parent.right=null;
				}
				resetTreeInformation(false);
				return;
			}

			if(replaceNode.colorRB=='b') {
				if(replaceNode.right!=null) {           				// 如果此时右子树不空那一定为红色用红代替黑即可,不用平衡
					removeNode.value=replaceNode.value;                 // 替换  删除节点
					replaceNode.value=replaceNode.right.value;          // 替换  替换节点
					replaceNode.right=null;                             // 删除替换节点叶子节点
				}else { 												
					balanceForRemove(replaceNode);                      // 如果  删除节点没有子节点,在移除节点之前先平衡,平衡之后删除
					removeNode.value=replaceNode.value;                 // 替换  删除节点
					if(replaceNode.parent==null) {                      // 只有一个根节点,直接删除
						this.root=null;
						this.TREEDEPTH=0;
						this.SIZE=0;
						return;
					}else if(replaceNode.value<replaceNode.parent.value) {    // 删除  替换节点
						replaceNode.parent.left=null;
					}else {
						replaceNode.parent.right=null;
					}
				}
				resetTreeInformation(false);
			}
			
		}
//		else {
//			System.out.println("实际删除的节点是:该节点不存在。");
//		}
	}
	
	private TreeNode findRemoveTargetNode(TreeNode nodeIndex, int value) {
		if( value < nodeIndex.value && nodeIndex.left!=null) return findRemoveTargetNode(nodeIndex.left,value);
		if( nodeIndex.value == value ) return nodeIndex;
		if( nodeIndex.value < value && nodeIndex.right!=null) return findRemoveTargetNode(nodeIndex.right,value);
		return null;
	}

	private void balanceForRemove(TreeNode replaceNode) {

		if(replaceNode.parent==null) return;      // 无需再平衡
		
		if(replaceNode.colorRB =='r') {           // 替换节点是红色(初始时没有,平衡递归之后会出现该情况),
			replaceNode.colorRB = 'b';            // 该情况直接改成黑色,其它都平衡了,结束
			return;
		}
		
		// 如果替换节点是黑节点,一定有兄弟节点
		if(replaceNode.value < replaceNode.parent.value) {            // 如果当前节点在父节点的左边
			
			if(replaceNode.parent.right.colorRB=='r') {		          // 如果当前节点的兄弟节点是红节点,转成黑黑的情况,重新平衡
				rotateLeft(replaceNode.parent);
				replaceNode.parent.colorRB='r';
				replaceNode.parent.parent.colorRB='b';
				balanceForRemove(replaceNode);                        // 继续进行平衡,后话此时其实只要再把兄弟节点变成红而父节点变成黑即可
				return;                                
			}
			
			if(replaceNode.parent.right.colorRB=='b' && replaceNode.parent.right.right!=null ) { 
				if( replaceNode.parent.right.right.colorRB=='r') {    // 如果当前节点的兄弟节点是黑节点且有红右子节点
					char pColor=replaceNode.parent.colorRB;
					
					rotateLeft(replaceNode.parent);                   // 进行左旋
					
					replaceNode.parent.colorRB='b';
					replaceNode.parent.parent.colorRB=pColor;
					replaceNode.parent.parent.right.colorRB='b';
					return ;
				}
			}
			
			if(replaceNode.parent.right.colorRB=='b' && replaceNode.parent.right.left!=null) {              
				if( replaceNode.parent.right.left.colorRB=='r') {      // 如果当前节点的兄弟节点有红左子节点
					
					rotateRight(replaceNode.parent.right);
					replaceNode.parent.right.right.colorRB='r';
					replaceNode.parent.right.colorRB='b';
					
					char pColor=replaceNode.parent.colorRB;
					rotateLeft(replaceNode.parent);                   // 进行左旋
					replaceNode.parent.colorRB='b';
					replaceNode.parent.parent.colorRB=pColor;
					replaceNode.parent.parent.right.colorRB='b';
					
					return ;
				}
			}
			
			// 兄弟为黑,且兄弟左右子树没有红
			replaceNode.parent.right.colorRB='r';
			balanceForRemove(replaceNode.parent);                      // 向上递归,自底向上处理
			return;
		}
		
		// 如果当前节点在父节点的右边
		if(replaceNode.parent.value < replaceNode.value) {             
			
			if(replaceNode.parent.left.colorRB=='r') {		           // 如果当前节点的(左)兄弟节点是红节点
				rotateRight(replaceNode.parent);					   // 进行右旋	
				replaceNode.parent.colorRB='r';
				replaceNode.parent.parent.colorRB='b'; 
				balanceForRemove(replaceNode);                         // 继续进行平衡,后话此时其实只要再把兄弟节点变成红而父节点变成黑即可
				return;                                 
			}
			
			if(replaceNode.parent.left.colorRB=='b' && replaceNode.parent.left.left!=null ) { 
				if( replaceNode.parent.left.left.colorRB=='r') {       // 如果当前节点的兄弟节点是黑节点且有红左子节点
					char pColor=replaceNode.parent.colorRB;
					
					rotateRight(replaceNode.parent);                   // 进行右旋
					
					replaceNode.parent.parent.colorRB=pColor;
					replaceNode.parent.colorRB='b';
					replaceNode.parent.parent.left.colorRB='b';
					return ;
				}
			}
			
			// 如果当前节点的兄弟节点有红右子节点和黑左子树
			if(replaceNode.parent.left.colorRB=='b' && replaceNode.parent.left.right!=null) {              
				if(replaceNode.parent.left.right.colorRB=='r') {     
					rotateLeft(replaceNode.parent.left);
					replaceNode.parent.left.left.colorRB='r';
					replaceNode.parent.left.colorRB='b';
					
					char pColor=replaceNode.parent.colorRB;
					rotateRight(replaceNode.parent);                   // 进行右旋
					replaceNode.parent.parent.colorRB=pColor;
					replaceNode.parent.colorRB='b';
					replaceNode.parent.parent.left.colorRB='b';
					
					return ;
				}
			}
			
			// 兄弟为黑,且兄弟左右子树没有红
			replaceNode.parent.left.colorRB='r';
			balanceForRemove(replaceNode.parent);                      // 向上递归,自底向上处理
			return;
		}

	}

}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值