红黑树算法

public class RBTreeTest {
	
	private static enum Color{
		RED,
		BLACK
	}
	
	private static class Node {
		Integer data ; 
		Node parent;
		Node left;
		Node right;
		Color color;
		public Node(int data,Node parent){
			this.data = data;
			this.parent = parent;
			this.color = Color.RED;
		}
		@Override
		public String toString() {
			return "[color = "+color +" , data = "+data+"]";
		}
	}
	
	private static void setRootBlack(Node node) {
		node.color = Color.BLACK;
		root = node;
	}
	
	private static Node root = null;
	
	public static void main(String[] args) {
		int[] arr = {12 ,1 ,9 ,2 ,0 ,11, 7, 19 ,4 ,15 ,18 ,5 ,14, 13 ,10 ,16, 6 ,3 ,8 ,17};
		for(int i : arr)
			insert(i);
		System.out.println(root);
	}
	
	private static void insert(int data){
		/**
		 * 1、 找到对应的insert位置
		 * 2、 旋转 着色 
		 */
		Node node = findInsertIndex(root , data);
		/**
		 * case 1 : 父节点为空,当前节点是root涂成黑色
		 * case 2 : 父节点是黑色,不需要做处理
		 * case 3 : 父节点和叔叔都是红色,先将父节点和叔叔涂成黑色
		 *          然后将爷爷涂成红色,然后递归调用爷爷节点的fixupNode(g)
		 * case 4 : 父节点是红色,叔叔是黑色,并且 当前节点与父节点的左右属性相反
		 *         (例:父节点是爷爷的左节点 , 当前节点是父节点的右节点)
		 *         先左或右旋(注意调用旋转函数传递参数应该是父节点)
		 *         完成之后再递归调用fixupNode(p) 必然会执行case 5 
		 * case 5 : 父节点是红色,叔叔是黑色,并且当前节点与父节点的左右属性一致
		 * 			将父节点和爷爷节点都变色 ,然后旋转  rotate(g)
		 */
		fixupNode(node);
	}

	/**
	 * p : 父节点
	 * g : 爷爷节点
	 * u : 叔叔节点
	 * l : 左子节点
	 * r : 右子节点 
	 */
	private static void fixupNode(Node node) {
		Node p = node.parent;
		if(p == null)
			setRootBlack(node); //case 1
		else{
			if(p.color == Color.BLACK)
				return ; //case 2
			else{
				Node g = p.parent;
				Node u = findUncle(node);
				if(u != null && u.color == Color.RED){
					//case 3
					p.color = Color.BLACK;
					u.color = Color.BLACK;
					g.color = Color.RED;
					fixupNode(g);
				}else{
					if(isLeft(p)){
						if(isLeft(node)){
							//case 5
							p.color = Color.BLACK;
							g.color = Color.RED;
							rotateRight(g);
						}else{
							//case 4
							rotateLeft(p);
							fixupNode(p);
						}
					}else{
						if(isLeft(node)){
							//case 4
							rotateRight(p);
							fixupNode(p);
						}else{
							//case 5
							p.color = Color.BLACK;
							g.color = Color.RED;
							rotateLeft(g);
						}
					}
				}
			}
		}
	}

	private static void rotateLeft(Node n) {
		Node r = n.right;
		Node p = n.parent;
		Node t = r.left;
		if(p != null){
			if(isLeft(n))
				p.left = r;
			else
				p.right = r;
		}
		r.parent = p;
		r.left = n;
		n.parent = r;
		n.right = t;
		if(t != null)
			t.parent = n;
		if(p == null)
			root = n.parent;
	}
	
	private static void rotateRight(Node n){
		Node l = n.left;
		Node p = n.parent;
		Node t = l.right;
		if(p != null){
			if(isLeft(n))
				p.left = l;
			else
				p.right = l;
		}
		l.parent = p;
		l.right = n;
		n.parent = l;
		n.left = t;
		if(t != null)
			t.parent = n;
		if(p == null)
			root = n.parent;
	}

	private static boolean isLeft(Node g) {
		return g.parent == null || g == g.parent.left;
	}

	private static Node findUncle(Node node) {
		Node g = node.parent.parent;
		if(node.parent == g.left)
			return g.right;
		else
			return g.left;
	}

	private static Node findInsertIndex(Node node , int data) {
		if(node == null)
			return root = new Node(data,null);
		if(node.data > data){
			if(node.left == null)
				return node.left = new Node(data,node);
			return findInsertIndex(node.left,data);
		}else if(node.data < data){
			if(node.right == null)
				return node.right = new Node(data,node);
			return findInsertIndex(node.right,data);
		}else
			return node;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值