`
cjf068
  • 浏览: 34220 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

红黑树

 
阅读更多
红黑树 规则

* 1.每个节点不是红色就是黑色
* 2.根总是黑色
* 3.如果节点是红色,则它的两个子节点必须是黑色(反之则不一定)
* 4.从根到叶节点或空子节点的每条路径,必须包括相同数目的黑节点(空节点为黑色)
节点类:
package org.jf.alg.tree;

public class RBNode <T extends Comparable>{

	public static int COLOR_RED = 1;
	public static int COLOR_BLACK = 2;
	private RBNode left;
	private RBNode right;
	private RBNode parent;
	private int color = COLOR_RED;//实际上是父节点指向子节点链的颜色
	
	private T data;
	
	public RBNode(T data)
	{
		this.data = data;
	}
	
	public RBNode(int color,T data)
	{
		this.color = color;
		this.data = data;
	}
	
	
	public T value()
	{
		return this.data;
	}
	
	public void setParent(RBNode parent)
	{
		this.parent=parent;
	}
	
	public RBNode parent()
	{
		return this.parent;
	}
	
	public void setLeft(RBNode left)
	{
		this.left = left;
	}
	public RBNode left()
	{
		return this.left;
	}
	
	public void setRight(RBNode right)
	{
		this.right = right;
	}
	
	public RBNode right()
	{
		return this.right;
	}
	
//	public void setRed()
//	{
//		color=COLOR_RED;
//	}
	
	public void setColor(int color)
	{
		this.color = color;
	}
	
//	public void setBlack()
//	{
//		color=COLOR_BLACK;
//	}
	
	public boolean isRed()
	{
		return color==COLOR_RED;
	}
	
	public boolean isBlack()
	{
		return color==COLOR_BLACK;
	}
	

}


红黑树类:
package org.jf.alg.tree;

/**
 * 
 * 红黑树
 * 
 * @author junfeng.chen
 *
 * @param <T>
 */
public class RBTree <T extends Comparable>
{
	/**
	 * 
	 * 红黑树 规则
	 * 1.每个节点不是红色就是黑色
	 * 2.根总是黑色
	 * 3.如果节点是红色,则它的两个子节点必须是黑色(反之则不一定)
	 * 4.从根到叶节点或空子节点的每条路径,必须包括相同数目的黑节点(空节点为黑色)
	 * 
	 * 
	 * 
	 */
	
	private RBNode root;

	private int count;
	
	public RBTree()
	{
		
	}
	
	public void addData(T data)
	{
		if(data==null)
			return;
		if(root==null)
		{
			root = new RBNode(data);
			root.setColor(RBNode.COLOR_BLACK);
			count++;
			return;
		}
		else
		{
			RBNode node = new RBNode(data);
			RBNode<Comparable> pnode = findParent(root,data);
			if(pnode.value().compareTo(data)>0)//data<pnode -->left
			{
				pnode.setLeft(node);
			
			}
			else
			{
				pnode.setRight(node);
				
			}
			node.setParent(pnode);
			node.setColor(RBNode.COLOR_RED);
			this.fixAfterInsertion(node);
		}
		count++;
	}
	
	
	/**
	 * 
	 * 
	 * 
	 * 
	 * @param x  当前插入的节点
	 * @param parent 父节点
	 */
	private void fixAfterInsertion(RBNode x)
	{
		/**
		 * 以 x p g 分别表示当前插入的节点  x的父节点  和 x的祖父节点(即 p 的父节点)
		 * 
		 * 
		 * 调整节点保持红黑树性质,分三大类情况
		 * 1.p是黑色的  , 不用调整
		 * 2.p是红色的,x是g的一个外侧子孙
		 * 只要一次旋转和一些颜色变化
		 * {
		 * (1)改变g的颜色
		 * (2)改变p的颜色
		 * (3)以x的祖父节点g为顶点旋转(向x上升的方向旋转)
		 * {
		 * (3-1)若x是g外侧子孙节点,且为p的左子节点,右旋
		 * (3-2)若x是g的外侧子孙节点,且为p的右子节点,左旋
		 * }
		 * 
		 * }
		 * 
		 * 3.p是红色的,x是g的一个内存子孙
		 * 需要2次旋转和一些颜色变化
		 * {
		 * (1)改变x和g的颜色
		 * (2)以x的父节点p为顶点旋转(向着x上升的方向)
		 *    (2-1)若x是p的左子节点,右旋
		 *    (2-2)若x是p的右子节点,左旋
		 * (3)再以x的祖父节点为顶旋转(向x上升的方向)
		 *    
		 * 
		 * }
		 * 
		 * 
		 */
		RBNode p=x.parent();
		//case1
		if(p==null||p.isBlack())
			return;
		RBNode g=p.parent();
		int flag=0;//left +1 right -1  if(flag=0) 内侧 else 外侧
		if(p==g.left())
		{	flag+=1;
			if(x==p.left())
				flag+=1;
			else
				flag+=-1;
		}else
		{
			flag+=-1;
			if(x==p.left())
				flag+=1;
			else
				flag+=-1;
		}
		
		//case2
		if(flag!=0)//
		{
			if(g.isBlack())
				g.setColor(RBNode.COLOR_RED);
			else g.setColor(RBNode.COLOR_BLACK);
			
			p.setColor(RBNode.COLOR_BLACK);
			
			if(x==p.left())
				this.rotateRight(g);
			else
				this.rotateLeft(g);
		}
		else
		{
			boolean right = false;
			if(p==g.right())
				right=true;
			x.setColor(RBNode.COLOR_BLACK);
			if(g.isBlack())
				g.setColor(RBNode.COLOR_RED);
			else
				g.setColor(RBNode.COLOR_BLACK);
			if(x==p.left())
				this.rotateRight(p);
			else
				this.rotateLeft(p);
			
			if(right)
				this.rotateLeft(g);
			else
				this.rotateRight(g);
		}
		
		
		//x 是g的外侧子孙
		//x 是g的内侧子孙
	}
	
	/**
	 * 
	 * 参考算法导论
	 * 右旋
	 *    x y y.right
	 *    旋转支点为x  其左子节点为y,左子节点的由子节点为r
	 *    y成为新的根(取代p的位置)
	 *    x成为y的右孩子
	 *    y的左孩子的右孩子成为x的左孩子
	 *   
	 *   y=x.left
	 *   x.left=y.right
	 *   y.right.parent=x
	 *   y.parent=x.parent
	 *   
	 *   if x.parent is null // x is root
	 *    then root = y
	 *   else if x==x.parent.left
	 *   then x.parent.left=y
	 *   else x.parent.right=y
	 *   y.right=x;
	 *   x.parent=y;
	 * 
	 * @param p
	 */
	private void rotateRight(RBNode x)
	{
		
		RBNode y=x.left(); 
		x.setLeft(y.right());
		if(y.right()!=null)
		y.right().setParent(x);
	    y.setParent(x.parent());
	    
	    if(x.parent()==null)
	    	root=y;
	    else if(x==x.parent().left())
	    	x.parent().setLeft(y);
	    else
	    	x.parent().setRight(y);
	    y.setRight(x);
	    x.setParent(y);
	}
	
	/**
	 * 左旋
	 * x y y.left
	 * 旋转支点为x 其右子节点为y 右子节点的左子节点为left
	 * 
	 * y成为新的根
	 * x成为y的左孩子
	 * y的左孩子成为x的右孩子
	 * 
	 * 
	 * y=x.right
	 * x.right=y.left
	 * y.left.parent=x
	 * y.parent=x.parent
	 * 
	 * if x.parent is null // x is tree root
	 * then root=y
	 * else if x=x.parent.left 
	 *      then x.parent.left=y
	 * else x.parent.right=y
	 * y.left=x;
	 * x.parent=y
	 * 
	 * 
	 * @param p
	 */
	private void rotateLeft(RBNode x)
	{
		RBNode y=x.right();
		x.setRight(y.left());
		if(y.left()!=null)
		y.left().setParent(x);
		y.setParent(x.parent());
		
		if(x.parent()==null)
			root=y;
		else if(x==x.parent().left())
			x.parent().setLeft(y);
		else x.parent().setRight(y);
		y.setLeft(x);
		x.setParent(y);
		
	}
	
	private RBNode findParent(RBNode<Comparable> root,Comparable data)
	{
		/**
		 * 与根比较 
		 * if data>=root
		 * 则查看右子树 如果右子树不存在 则返回根
		 *                     否则 在右子树中查找
		 *else
		 * 则查找左子树  如果左子树存在 则返回根
		 *                      否则 在左子树中查找                    
		 */
		RBNode left = root.left();
		RBNode right = root.right();
		Comparable value_root = root.value();
		if(data.compareTo(value_root)>=0)//右子树
		{
			if(right==null)
				return root;
			else
			{
				return findParent(right, data);
			}
		}
		else//左子树
		{
			if(left==null)
				return root;
			else
				return findParent(left,data);	
		}
		
	}
	
	public boolean contains(T data)
	{
		return false;
	}
	
	public int getCount()
	{
		return this.count;
	}
	
	
	public static void main(String args[])
	{
		RBTree rbTree = new RBTree();
		for(int i=0;i<10;i++)
		{
			rbTree.addData(i);
		}
		
	}
	
	
}

分享到:
评论

相关推荐

    红黑树-动态演示生成红黑树

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家鲁道夫·贝尔在1978年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高了数据操作的效率。红黑树的主要目标是保证在...

    红黑树的源码与测试函数

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它的每个节点都带有颜色属性,可以是红色或黑色。这种数据结构被广泛应用于计算机科学的许多领域,特别是操作系统、数据库系统以及编译器中,用于高效地执行插入、...

    红黑树原理详解

    红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年发明。它的名称来源于其节点颜色属性,即红色和黑色。红黑树的主要特性保证了其在插入、删除和查找操作中的高效性能,通常时间复杂度为O(log n),其中n是树中...

    红黑树-使用C++实现-简单练习

    红黑树是一种自平衡二叉查找树,由Rudolf Bayer于1972年提出。它的设计目标是在保持二叉查找树基本属性的同时,通过引入颜色(红色或黑色)来保证树的平衡,从而在插入和删除操作后能够快速恢复平衡状态,减少查找、...

    红黑树的插入与删除_详细整理资料

    ### 红黑树的插入与删除:详细解析 红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年发明,最初被称为“对称二叉B树”。它在1978年Leo J. Guibas和Robert Sedgewick的论文中获得了现代名称“红黑树”。红黑树...

    红黑树和AVL树的实现

    红黑树和AVL树是两种自平衡二叉查找树,它们在计算机科学中的数据结构领域扮演着重要的角色,主要用于高效地存储和检索数据。这两种数据结构的主要目标是在插入和删除操作后保持树的平衡,从而确保搜索、插入和删除...

    红黑树java操作代码 红黑树是java里面遍历性能最好数据结构

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在实现高效的数据结构和算法时。在Java中,虽然标准库并未直接提供红黑树的类,但我们可以自定义实现,如提供的`Red...

    红黑树完整实现文件

    红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年提出。它的设计目标是在保持二叉查找树基本属性的同时,通过引入颜色(红色或黑色)来保证树的平衡,从而提高查找、插入和删除操作的效率。在红黑树中,每个...

    红黑树代码

    红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树...

    gcc 红黑树(二叉搜索树 红黑树 动态排序树 精确计时)

    红黑树是一种自平衡二叉查找树,它的设计目的是为了在保持查找效率的同时,尽可能地减少插入和删除操作带来的性能损失。在计算机科学中,它是一种广泛应用的数据结构,特别是在动态排序和高效查找方面。 二叉搜索树...

    Linux内核红黑树封装的通用红黑树

    通用红黑树 说明: 用Linux内核红黑树封装的一个通用型的红黑树 如何使用该红黑树: 见rbtest1.c和rbtest2.c 直接make生成rbtest1和rbtest2 作者:rcyh 日期:2011年7月21日 ---------------------------------...

    红黑树的C实现,算法导论的红黑树C实现

    红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年提出。它的设计目标是在保持二叉查找树基本性质的同时,通过引入颜色属性来保证树的平衡,从而达到高效的插入、删除和查找操作。红黑树的关键特性是: 1. 每...

    红黑树的例子

    ### 红黑树知识点详解 #### 一、红黑树定义与性质 红黑树是一种自平衡二叉查找树,其每个节点除了保存键值、左子节点、右子节点和父节点的信息外,还额外保存了一个表示颜色的属性(红色或黑色)。红黑树在进行...

    红黑树、区间树

    红黑树和区间树是两种在计算机科学中广泛使用的数据结构,主要应用于高效的数据存储和检索。它们在算法和数据结构领域具有重要地位,尤其在处理动态集合或需要快速查找和更新操作的问题时。 首先,我们来详细了解...

    红黑树-数据结构

    红黑树是一种自平衡二叉查找树(self-balancing binary search tree),由计算机科学家Rudolf Bayer在1972年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高数据操作的效率。在红黑...

    红黑树实现源码

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性被用来确保树的某些关键性质,...

    红黑树的插入详细图解,直接拿下红黑树

    红黑树是一种自平衡二叉查找树,它的主要特点是在保持二叉查找树特性的同时,通过特定的颜色规则来确保树的平衡,以达到快速查找、插入和删除的目的。红黑树的每个节点都有一个颜色属性,可以是红色或黑色。在插入新...

    用c实现的红黑树,经典的红黑树,

    红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年提出。它的设计目标是在保持查询效率高的同时,尽可能地减少由于插入和删除操作引起的树的不平衡。红黑树的主要特点包括: 1. **颜色属性**:每个节点都有...

    红黑树Java实现

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性用于确保树的平衡,使得在树中的...

    delphi红黑树源码

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。它在数据结构和算法领域具有重要地位,被广泛应用于各种系统和软件中,包括数据库索引、编译器、虚拟机等。在Delphi编程...

Global site tag (gtag.js) - Google Analytics