java 实现红黑树

package 红黑树;


public class Red_Black_Tree {
	public Node root;
	
	
	
	//二叉树的:中序遍历
			int m=0;
			
			public void inOrder(Node temp){
				
				if(temp!=null){
					inOrder(temp.left);
					System.out.println("--中序--"+temp.value.data);
					inOrder(temp.right);
				}
				
			}
		public void printInOrder(){
		}
		public void print(Node temp){
			while(temp!=null){
				if(temp.left!=null){
					System.out.println("--中序--"+temp.value.data);	
					temp=temp.left;
				}else if(temp.right!=null){
					System.out.println("--中序--"+temp.value.data);
					temp=temp.right;
				}
				if(temp.parent==null){
					System.out.println("--中序--"+temp.value.data);	
					temp=temp.right;
				}
				
			}
		}
			
	public void inOrder(){
		//print(root);
		inOrder(root);
	}
	public void insert(Object obj){
		
		if(root != null){
			root = insert(root,obj);			
		}else{
			root=new Node(obj);
			root.color=1;//根节点置黑
		}
		
	}
	public Node insert(Node rot, Object obj){
		
		if(rot==null){
			rot=new Node(obj);
			
			return rot;
		}
		if(obj.data==rot.value.data){
			System.out.println("已存在!");
		}
		
		
		
		
		
		if(obj.data<rot.value.data){
			//Node node=rot;
			rot.left=insert(rot.left, obj);//递归查找插入
			//rot.left.parent=rot;		//设置父亲节点
			if(rot.parent != null)
			if(rot.parent.right==null || rot.parent.color==1){//根节点右孩子为黑
				if(rot.color==0 && rot.parent.left==rot){//情况1,向右旋转一次	R_R()
					rot=R_R(rot);
				}else if(rot.color==0 && rot.parent.right==rot){//情况3,首先向右旋转一次,再向左旋转一次 	R_L
					
				}
			}else if(rot.parent.color==0){//右孩子为红(比较麻烦)
				
			}
			
			
			
		}else if(obj.data>rot.value.data){//与左子树相对
			rot.right = insert(rot.right, obj);//递归查找插入
			rot.right.parent = rot;		//设置父亲节点
			if(rot.parent.left==null || rot.parent.color == 1){//根节点左孩子为黑
				if(rot.color==0 && rot.parent.left==rot){//情况2,向左旋转一次 L_L
					
				}else if(rot.color==0 && rot.parent.right==rot){//情况4,首先向左旋转一次, 再向右旋转一次  	L_R
					
				}
			}else if(rot.parent.color==0){//左孩子为红比较麻烦
				
			}
			
			
			
			
			
		}
		return rot;
	}
	
	public void put(Object obj){
		root = put(root, obj);
	}
	public Node put(Node rot, Object obj){
		Node temp = null;
		if(root != null){
			Node node=rot;
			boolean isLeft = false;
			while(node !=null){//找到需要插入的位置,并用isLeft记录需要插入的位置是左子树或右子树
				temp=node;
				if(obj.data<node.value.data){
					node=node.left;
					isLeft=true;
				}else if(obj.data>node.value.data){
					node=node.right;
					isLeft=false;
				}else{
					System.out.println("已存在!");
					//return ;
				}
			}
			
			Node nod = new Node(obj);
			if(isLeft==true){//插入在任意节点的左子树
				temp.left=nod;
				nod.parent=temp;
				if(temp.color==1){
					return findRoot(temp);
				}
				/*调整 叔父节点为黑或空的情况
				 * 1.父节点为爷爷节点的左孩子 向右旋转R_R
				 * 2.父节点为爷爷节点的右孩子需要两次旋转 先右转R_R 在左旋转L_L
				 * 叔父节点为红色的情况:
				 * 3.若父亲节点为红色 且叔父节点为红色
				 * 	3.1 首先需要让其爷爷节点的颜色同时与其父节点和叔父节点交换
				 * 	3.2 然后再向上层回溯一次 则回到需要判断调整的四种方式上
				 */
				if(temp.parent!=null&&temp==temp.parent.left){//情况 1
					if(temp.parent.right==null||temp.parent.right.color==1){
						temp=R_R(temp);
					}else if(temp.parent.right.color==0){//情况3
						int pc=temp.parent.color;
						temp.parent.color=temp.color;
						temp.color=pc;
						temp.parent.right.color=pc;//颜色交换完成
						if(temp.parent==root){
							root.color=1;
						}
						
						//3.2 其爷爷节点要么在左子树上 要么在右子树上
						if(temp.parent.parent!=null){
							temp.parent.parent.parent=Tiaozheng(temp.parent.parent);							
						}
					/*	if(temp.parent.parent!=null&&temp.parent.color==temp.parent.parent.color&&temp.parent.color==0){
							if(temp.parent.parent==temp.parent.parent.parent.left){
								temp.parent.parent=R_R(temp.parent.parent);
							}else if(temp.parent.parent==temp.parent.parent.parent.right){
								temp.parent.parent=L_L(temp.parent.parent);
							}
						}*/

						
					}
					
				}else if(temp.parent!=null&&temp==temp.parent.right){//情况 2
					if(temp.parent.left==null || temp.parent.left.color==1){
						Node p=temp.parent;
						
						temp=R_R(temp.left);//先右旋转,再左旋转
						p.right=temp;
						temp.parent=p;
						
						//Node p1=//接上
						temp=L_L(temp);
						
						
					}else if(temp.parent.left.color==0){//情况3
				/*		Node p=temp.parent;
						temp=R_R(temp.left);//先右旋转,再左旋转
						p.right=temp;
						temp.parent=p;
				*/			
						int pc=temp.parent.color;
						temp.parent.color=temp.color;
						temp.color=pc;
						temp.parent.left.color=pc;//颜色交换完成
						if(temp.parent==root){
							root.color=1;
						}
						//3.2 其爷爷节点要么在左子树上 要么在右子树上
						if(temp.parent.parent!=null){
							temp.parent.parent.parent=Tiaozheng(temp.parent.parent);							
						}
					/*	if(temp.parent.parent!=null&&temp.parent.color==temp.parent.parent.color&&temp.parent.color==0){
							if(temp.parent.parent==temp.parent.parent.parent.right){
								temp.parent.parent=R_R(temp.parent.parent);
							}else if(temp.parent.parent==temp.parent.parent.parent.left){
								temp.parent.parent=L_L(temp.parent.parent);
							}
						}
						*/
					}
				}
				
				
				//Node ancle = temp.parent;
				
				
				
				
				
				
				
			}else{//插入在任意节点的右子树
				temp.right=nod;
				nod.parent=temp;
				if(temp.color==1){
					return findRoot(temp);
				}
				/*调整 叔父节点为黑或空的情况
				 * 1.父节点为爷爷节点的右孩子需要一次  左旋转L_L
				 * 2.父节点为爷爷节点的左孩子 需要两次旋转先L_L 再R_R
				 * 叔父节点为红色的情况:
				 * 
				 */
				if(temp.parent!=null&&temp==temp.parent.right){//情况 1
					if(temp.parent.left==null||temp.parent.left.color==1){
						temp=L_L(temp);
					}else if(temp.parent.left.color==0){
						int pc=temp.parent.color;
						temp.parent.color=temp.color;
						temp.color=pc;
						temp.parent.left.color=pc;//颜色交换完成
						if(temp.parent==root){
							root.color=1;
						}
						
						//3.2 其爷爷节点要么在左子树上 要么在右子树上
						if(temp.parent.parent!=null){
							temp.parent.parent.parent=Tiaozheng(temp.parent.parent);							
						}
						/*if(temp.parent.parent!=null&&temp.parent.color==temp.parent.parent.color&&temp.parent.color==0){
							if(temp.parent.parent==temp.parent.parent.parent.right){
								temp.parent.parent=R_R(temp.parent.parent);
							}else if(temp.parent.parent==temp.parent.parent.parent.left){
								temp.parent.parent=L_L(temp.parent.parent);
							}
						}*/
					}
					
					
				}else if(temp.parent!=null&&temp==temp.parent.left){//情况 2
					if(temp.parent.right==null || temp.parent.right.color==1){
						Node p=temp.parent;
						
						temp=L_L(temp.right);//先左旋转,再左旋转
						p.left=temp;
						temp.parent=p;
						
						//Node p1=//接上
						temp=R_R(temp);
						
						
					}else if(temp.parent.right.color==0){
						int pc=temp.parent.color;
						temp.parent.color=temp.color;
						temp.color=pc;
						temp.parent.right.color=pc;//颜色交换完成
						if(temp.parent==root){
							root.color=1;
						}
						
						//3.2 其爷爷节点要么在左子树上 要么在右子树上
						if(temp.parent.parent!=null){
							temp.parent.parent.parent=Tiaozheng(temp.parent.parent);							
						}
				/*		if(temp.parent.parent!=null&&temp.parent.color==temp.parent.parent.color&&temp.parent.color==0){
							if(temp.parent.parent==temp.parent.parent.parent.left){
								temp.parent.parent=R_R(temp.parent.parent);
							}else if(temp.parent.parent==temp.parent.parent.parent.right){
								temp.parent.parent=L_L(temp.parent.parent);
							}
						}*/
					}
				}
				
				
				
			}
			
			
		}else{
			root = new Node(obj);
			root.color=1;
			temp=root;
		}
		return findRoot(temp);
	}
	/**/
	 public Node Tiaozheng(Node node){//传入参数temp.parent.parent
	 	Node p = node.parent;
	 	if(p!=null&&p.parent!=null&&p.color==0&&p.parent.parent!=null){
	 		Node pp=p.parent;
	 		if(p==pp.left){
		 		if(node==p.left&&pp.right==null ||pp.right.color==1){
		 			p=R_R(p);
		 			return p;
		 		}else if(node==p.right&&pp.right==null ||pp.right.color==1){
		 			Node p1=p.parent;
					
					p=L_L(p.right);//先左旋转,再左旋转
					p1.left=p;
					p.parent=p1;
					
					//Node p1=//接上
					p=R_R(p);
					
					return p;
		 		}
	 		}else if(p==p.right){
	 			if(node==p.right&&pp.left==null ||pp.left.color==1){
	 				p=L_L(p);
	 				return p;
	 			}else if(node==p.left&&pp.left==null ||pp.left.color==1){
	 				Node p1=p.parent;
					
					p=R_R(p.left);//先右旋转,再左旋转
					p1.right=p;
					p.parent=p1;
					
					//Node p1=//接上
					p=L_L(p);
					return p;
	 			}
	 		}
	 	}
	 	return p;
	 }
	 
	public Node findRoot(Node node){
		Node temp=node;
		if(node==root){
			return root;
		}
		while(temp.parent!=null){
			temp=temp.parent;
		}
		return temp;
	}
	
	
	public Node R_R(Node rot){//向右旋转
		
		Node p=rot.parent;
		if(p!=null){
			p.left=null;			
		}
		//p.parent=null;
		rot.parent=null;
		
		
		Node r=rot.right;
		
		if(p!=null){
			if(p.parent!=null){
				Node temp = p.parent.left;
				p.parent.left=rot;
				rot.parent=p.parent;
				
				temp.parent=rot;
				rot.right=p;
				
			}else{
				rot.right=p;
				p.parent=rot;							
			}
			//p.parent=rot;			
		}
		
		if(r!=null){
			if(p!=null){			
				p.left=r;
			}
			r.parent=p;			
		}
		
		if(p!=null){			
			int cc=p.color;
			p.color=rot.color;
			rot.color=cc;
		}
		
		return rot;
		
	}
	public Node L_L(Node rot){//向左旋转
		Node node=rot.parent;
		if(node!=null){
			node.right=null;			
		}
		rot.parent=null;
		
		Node l=rot.left;
		if(node != null){
			if(node.parent!=null){
				Node temp = node.parent.right;
				node.parent.right=rot;
				rot.parent=node.parent;
				
				temp.parent=rot;
				rot.left=node;
				
			}else{
				rot.left=node;
				node.parent=rot;							
			}
		}
		
		if(l!=null){
			if(node !=null){
				node.right=l;							
			}
			l.parent=node;
		}
		
		if(node!=null){
			int cc=node.color;
			node.color=rot.color;
			rot.color=cc;			
		}else{
			
		}
		
		
		return rot;
	}
	public Node R_L(Node rot){//先右旋转,再左旋转
		Node node=R_R(rot);
		node=L_L(node);	
		return node;
		
	}
	public Node L_R(Node rot){//先左旋转 ,再右旋转
		Node node=L_L(rot);
		node = R_R(node);
		return node;
		
	}
	
	
	public void remove(Object obj){
		remove(root, obj);
	}
	public void remove(Node rot,Object obj){
		Node node = find(obj);
		
		if(node==null){
			System.out.println("不存在!");
		}else if(node.left==null&&node.right==null){//删除的是叶子节点,直接删除不会影响平衡
			node.parent.left=null;
		}else if((node.left==null&&node.right!=null )|| (node.right==null && node.left!=null)){//被删除的节点只有一个子节点
			if(node.left==null&&node.right!=null ){
				if(node.color==0){//若删除节点为红色直接删除 	
					node.color=node.right.color;
					node.value=node.right.value;
					node.right=null;
				}else{//黑色
					node.color=1;
					node.value=node.right.value;
					node.right=null;
				}
			}else{
				if(node.color==0){//若删除节点为红色直接删除 	
					node.color=node.left.color;
					node.value=node.left.value;
					node.left=null;
				}else{//黑色
					node.color=1;
					node.value=node.left.value;
					node.left=null;
				}
				
			}		
		}else if(node.left!=null&&node.right!=null){//被删除节点有两个子节点
			Node temp = findM(node.left);
			if(node.color==0){//被删除为红色
				//node.color=temp.color;
				node.value=temp.value;
			}else{//被删除为黑色
				node.color=1;
				node.value=temp.value;
			}
			/*节点删除之后现在仅需判断temp即可
			 * 首先判断tmep是否存在右孩子:若存在则接上,若不存在直接删除temp,额 肯定不存在
			 * 
			 * 这又回到了四种情况的调整只是需要把temp置空
			 * 判断其兄弟节点是否为红或黑
			 * 黑:
			 * 红: 
			 */
			Node nod = temp.parent;
			nod.left=null;
			temp=null;
			if(nod.right.color==1){//兄弟节点为黑
				if(nod.color==1){
					Tiaozheng(nod);
				}else{	
					
					inOrder();
					nod.right=L_L(nod.right);
				}
			}else if(node.right.color==0){//兄弟节点为红色
				nod.right=L_L(nod.right);
				
			}
			
		}
		
		
		
		
		
		
	}
	
	public Node findM(Node t){//查找右子树中的最小值
		Node node=findMin(t);
		Node temp=node;
		//node.parent.left=null;
		//temp.parent=null;
		return temp;
	}
	public Node findMin(Node t){  
        if(t == null)  
            return null;  
        if(t.left == null)  
            return t;  
        return findMin(t.left);  
    }
	public Node find(Object obj){
		return find(root,obj);
	}
	public Node find(Node node, Object obj){
		if(node!=null&&node.value.data==obj.data){
			return node;
		}
		if(node!=null){
		Node nod = find(node.left, obj);
		if(nod!=null&&nod.value==obj){
			return nod;
		}
		}
		if(node!=null){			
		Node nod1 = find(node.right, obj);
		if(nod1!=null&&nod1.value==obj){
			return nod1;
		}
		}
		return null;
	}
	
	
	
	
	
	
	
	
	
	
	
	
}
class Node{
	public Node left;
	public Node right;
	public Node parent;
	public int color;//0表示红色,1表示黑色
	public Object value;
	public Node(Object obj){
		this.value=obj;
		this.left=this.right=this.parent=null;
		this.color=0;
	}
}

package 红黑树;

public class Object {
	int data;
	
	public Object(int a){
		this.data=a;
	}
	
}

package 红黑树;

public class Test {
	public static void main(String args[]){
		Red_Black_Tree tree = new Red_Black_Tree();
		
	/*	for(int i=0;i<28;i++){
			Object Mathobj = new Object(i*2);
			//System.out.println((int)(Math.random()*100)+10);(int)(Math.random()*100)+
			tree.put(Mathobj);
		}
		tree.inOrder();
	*/	
		
		Object obj = new Object(50);
		Object obj1 = new Object(35);
		Object obj3 = new Object(27);
		Object obj4 = new Object(56);
		Object obj5 = new Object(90);
		Object obj6 = new Object(45);
		Object obj7 = new Object(41);
		Object obj8 = new Object(48);
		Object obj9 = new Object(40);
		Object obj10 = new Object(36);
		
		
		
		tree.put(obj9);
		tree.put(obj);
		tree.put(obj1);
		tree.put(obj3);
		tree.inOrder();
		System.out.println("------1--------");
		tree.put(obj4);		
		tree.inOrder();
		System.out.println("------2--------");
		tree.put(obj5);		
		tree.inOrder();
		System.out.println("------3--------");
		tree.put(obj6);		
		tree.inOrder();
		System.out.println("------4--------");
		tree.put(obj7);		
		tree.inOrder();
		System.out.println("------5--------");
		tree.put(obj8);				
		tree.inOrder();
		System.out.println("------6--------");
		
		tree.put(obj10);				
		tree.inOrder();
		System.out.println("------7--------");
		
		tree.remove(obj);
		tree.inOrder();
		System.out.println("------8--------");
		
		
		
		
		

		
		
	}
}
...大哭(这个比平衡树要复杂)有机会回头再弄一遍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值