红黑树插入算

算法步骤:

    (1).第一步BST树规则将结点z插入红黑树中从树根开始搜索,如果插入值比节点大,就向右子树搜索,比节点小则向左子树搜索。直到走到叶节点位置,将插入值放在这个节点上。此节点为叶子节点。将他标记为红色。

(2)插入z后可能违反红黑树性质24。对于违反性质2只需将根节点涂黑即可。对于违反性质4,可以分成6中情况。其中根据z的父节点是z的祖节点的左子节点还是右子节点,分为两组对称的情况,每组有3种情况。因为两组是对称的,我们讨论z的父节点是z的祖节点的左子节点的三种情况。

Case1z叔叔节点y是红色

z父、叔节点都着为黑色,再z的祖父节点着为红色,再将z指向子树的根节点,向上递归恢复红黑特性。

Case2z叔叔节点y是黑色,其z是双亲的右孩子

z指向其父节点,再将左旋z节点,则情况转化为case3

Case3z叔叔节点y是黑色,其z是双亲的左孩子

z的父节点与祖节点进行一次右旋,并把父节点着黑色,原来的祖节点着红色。这些子树的红黑特性得到了恢复,而且子树的黑高度没有变化

这样,红黑树的节点插入问题就得到了解决。

实验随机插入1000个节点,并将树高打印出来。

其代码:

package rb;

public class RBTreeNode {
	public RBTreeNode p;
	public RBTreeNode left;
	public RBTreeNode right;
	public int key;
	public String color;
	public RBTreeNode() {}
	public RBTreeNode(int key)
	{
		this.key = key;
	}
}


package rb;

public class RBTree {
	public RBTreeNode root; 
	/*对x节点左旋转  */
	public static void Left_Rotate(RBTree rb,RBTreeNode x)
	{
		RBTreeNode y = x.right;  //set y
		x.right = y.left;        //turn y's left subtree into x's right subtree
		if(y.left!=null)
		{
			y.left.p = x;
		}
		y.p = x.p;               //link x's parent to y
		if(x.p == null)
			rb.root = y;
		else if (x == x.p.left )
		{
			x.p.left = y;
		}
		else
			x.p.right = y;
		y.left = x;             //put x on y's left
		x.p = y;	
	}
	/*对y节点右旋转  */
	public static void Right_Rotate(RBTree rb,RBTreeNode y)
	{
		RBTreeNode x = y.left; //set x
		y.left = x.right;      //turn x's left subtree into y's right subtree
		if(x.right!=null)
		{
			x.right.p = y;
		}
		x.p = y.p;             //link y's parent to x
		if(y.p == null)
			rb.root = x;
		else if (y == y.p.left )
		{
			y.p.left = x;
		}
		else
			y.p.right = x;
		x.right = y;            //put y on x's right
		y.p = x;	
	}


	/*在rb中插入z节点 */
	public static void rb_insert(RBTree rb,RBTreeNode z){
		if(z==null)return;
		RBTreeNode y= null;   //用于记录当前扫描节点的双亲节点
		RBTreeNode x= rb.root;//从根节点开始查找
		/*查找插入位置*/
		while(x != null){
			y=x;
			if(z.key < x.key)
				x = x.left;
			else
				x = x.right;
		}
		z.p = y;// 将z插入y之后,即y是z的双亲
		if(y == null)
		{
			rb.root = z;
		}
		else if(z.key < y.key)
		{
			y.left = z;
		}
		else
		{
			y.right = z;
		}
		z.left = null;
		z.right = null;
		z.color = "RED";
		rb_insert_fixup(rb,z);
	}
	public static void rb_insert_fixup(RBTree rb, RBTreeNode z) {
		// TODO Auto-generated method stub
		while(z.p != null && z.p.color.equals("RED"))
		{
			if((z.p.p != null) && (z.p == z.p.p.left))   //case1-case3 z的父节点是其祖父节点的左孩子
			{
				RBTreeNode y = z.p.p.right;     //y是z的叔叔节点
				if((y != null) && y.color.equals("RED"))  //case1
				{
					z.p.color = "BLACK";
					y.color = "BLACK";
					z.p.p.color = "RED";
					z = z.p.p;
				}
				else{
					if(z == z.p.right)//case2
					{
						z = z.p;
						Left_Rotate(rb, z);
					}
					z.p.color = "BLACK";//case3
					z.p.p.color = "RED";
					Right_Rotate(rb, z.p.p);
				}
			}


			else if((z.p.p != null) && (z.p == z.p.p.right))   //case4-case6 z的父节点是其祖父节点的右孩子
			{
				RBTreeNode y = z.p.p.left;     //y是z的叔叔节点
				if((y != null) && y.color.equals("RED"))  //case4
				{
					z.p.color = "BLACK";
					y.color = "BLACK";
					z.p.p.color = "RED";
					z = z.p.p;
				}
				else{
					if(z == z.p.left)//case5
					{
						z = z.p;
						Right_Rotate(rb, z);
					}
					z.p.color = "BLACK";//case6
					z.p.p.color = "RED";
					Left_Rotate(rb, z.p.p);
				}
			}
		}
		rb.root.color = "BLACK";
	}


	/*红黑树高*/
	public static int High(RBTreeNode root)
	{
		int left_h ;
		int right_h ;
		if(root == null)
		{
			return 0;
		}
		else{


			left_h = High(root.left);
			right_h=High(root.right);
			return (left_h>right_h?left_h+1:right_h+1);
		}


	}
}




package rb;

import java.util.Random;

public class Test {
 

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int height = 0;
		Random rd = new Random();
		RBTree rb = new RBTree(); 
		for(int i = 0; i < 1000; i++)
		{
			RBTree.rb_insert(rb,new RBTreeNode(rd.nextInt(1000)));
		}
		height=RBTree.High(rb.root);
		System.out.println("红黑树高:"+height); 
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值