红黑树的简单插入

  1. p,u遍黑色,z变红色
  2. p变黑色,z变红色,以p为轴,pz为半径右旋。
  3. 以x为轴,px为半径左旋(x向上走),得到二图情形。
class Node {
	int data;
	boolean isRed;//是红节点还是黑节点
	Node parent;
	Node leftChiled;
	Node rightChiled;
	public Node(int data) {
		this.data=data;
		isRed=true;
	}
}
public class RedBlackTree {
	private static Node root;
	public void insert(int id) {
		Node newNode=new Node(id);
		if(root==null) {
			root=newNode;
			root.parent=null;
			root.isRed=false;//根节点总是黑色,规则2
		} else {
			Node curParent=root;
			Node current=root;
			while(true) {
				curParent=current;
				if(id<current.data) {
					current=current.leftChiled;
					if(current==null) {
						current=newNode;
						curParent.leftChiled=current;
						current.parent=curParent;
						break;
					}
				} else {
					current=current.rightChiled;
					if(current==null) {
						current=newNode;
						curParent.rightChiled=current;
						current.parent=curParent;
						break;
					}
				}
			}
			//判断是否平衡,变色旋转
			insertFix(current);
		}
	}

	public void insertFix(Node node) {
		while(node.parent!=null&& node.parent.isRed ) {
			if(node.parent==node.parent.parent.leftChiled) {	//左子节点
				//判断叔叔节点是黑色还是红色
				Node y=node.parent.parent.rightChiled;
				if(y.isRed) {
					//父节点,祖父节点,叔叔节点都变成相反颜色
					node.parent.isRed=false;
					node.parent.parent.isRed=true;
					node.parent.parent.rightChiled.isRed=false;
					node=node.parent.parent;
				} else if(node==node.parent.rightChiled) {//右子树
					node=node.parent;
					leftRotate(node);
				} else {
					//父节点,祖父节点变色
					node.parent.isRed=false;
					node.parent.parent.isRed=true;
					//node=node.parent;
					rightRotate(node.parent.parent);
				}
			} else {//父节点是祖父节点的右子节点
				//判断叔叔节点是黑色还是红色
				Node y=node.parent.parent.leftChiled;
				if(y.isRed) {
					//父节点,祖父节点,叔叔节点都变成相反颜色
					node.parent.isRed=false;
					node.parent.parent.isRed=true;
					node.parent.parent.leftChiled.isRed=false;
					node=node.parent.parent;
				} else if(node==node.parent.leftChiled) {//右子树
					node=node.parent;
					rightRotate(node);
				} else {
					//父节点,祖父节点变色
					node.parent.isRed=false;
					node.parent.parent.isRed=true;
					//node=node.parent;
					leftRotate(node.parent.parent);
				}
			}
		}
		root.isRed=false;
	}
	//以x为轴进行右旋
	public void leftRotate(Node x) {
		if(x==null) return ;
		Node y=x.leftChiled;//x的左子节点
		x.leftChiled=y.rightChiled;
		if(y.rightChiled!=null) {
			y.leftChiled.parent=x;
		}
		y.parent=x.parent;
		if(x.parent==null) {//x为根节点
			root=y;
		} else if(x==x.parent.leftChiled) {
			y.parent.leftChiled=y;
		} else {
			y.parent.rightChiled=y;
		}
		y.rightChiled=x;
		x.parent=y;
	}
	//以x为轴进行左旋
	public void rightRotate(Node x) {
		if(x==null) return ;
		Node y=x.rightChiled;
		x.rightChiled=y.leftChiled;
		if(y.rightChiled!=null) {
			y.rightChiled.parent=x;
		}
		y.parent=x.parent;
		if(x.parent==null) {
			root=y;
		} else if(x.parent.leftChiled==x) {
			y.parent.leftChiled=y;
		} else {
			y.parent.rightChiled=y;
		}
		y.leftChiled=x;
		x.parent=y;
	}
	/**
	 * 中序遍历
	 * @param node
	 */
	public void orderTraversal(Node root) {
		if(root!=null) {
			orderTraversal(root.leftChiled);
			System.out.print(root.data+" ");
			orderTraversal(root.rightChiled);
		}
	}
	public static void main(String[] args) {
		RedBlackTree rbt=new RedBlackTree();
		int[] a=new int[]{50,25,75,12,37,62,87,6,18,31,43};
		for(int i=0;i<a.length;i++) {
			rbt.insert(a[i]);
		}
		rbt.orderTraversal(root);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值