数据结构--搞懂红黑树

  名为搞懂红黑树,所以一些最基本的概念定义就不再赘述,书上和网上一大堆资料,我学习的资料是算法第四版,参考博客http://blog.youkuaiyun.com/u010425776/article/details/60970433,重在理解红黑树这一数据结构。

首先要知道的就是红黑树的性质,违反这几条性质就不能称为红黑树,接下来的关于红黑树的操作前提就是不违反这些性质。

红黑树的性质:

  1. 1、每个结点或是红色的,或是黑色的 
    2、根节点是黑色的 
    3、每个叶结点(NIL)是黑色的 
    4、如果一个节点是红色的,则它的两个儿子都是黑色的。 
    5、对于每个结点,从该结点到其叶子结点构成的所有路径上的黑结点个数相同

java实现:

  private class Node{
    	Key key;//键
    	Value value;//相关联的值
    	Node left,right;//左右子树
    	int N;//这颗子树中的结点总数
    	boolean color;//由其父结点指向它的链接的颜色
    	
    	Node(Key key,Value value,int N,boolean color){
    		this.key=key;
    		this.value=value;
    		this.N=N;
    		this.color=color;
    	}
    }

插入操作:

  向一颗含有n个节点的红黑树中插入一个节点,可以在时间O(lgn)内完成。

    将节点z插入红黑树T内。需要执行的操作依次时:首先,将T当作一颗二叉树,将z插入;然后,将z着色为红色;最后,对节点重新着色并旋转,以此来保证删除节点后的树仍然是一颗红黑树。

    所以有两个操作我们先需要搞懂,1.旋转。2。重新着色。用来保证插入之后符合红黑树的性质。

1.旋转


1. 父为黑

title 
插入后无需任何操作。由于黑节点个数至少为红节点的两倍,因此父为黑的情况较多,而这种情况在插入后无需任何调整,这就是红黑树比AVL树插入效率高的原因!

2. 父为红

父为红的情况破坏了红黑树的性质,此时需要根据叔叔的颜色来做不同的处理。 
title

  1. 叔叔为红 
    title 
    此时很简单,只需交换爸爸、叔叔和爷爷的颜色即可。 
    此时若爷爷节点和太爷爷节点颜色相同,再以爷爷节点为起始节点,进行刚才相同的操作,即:根据爷爷的兄弟颜色做相应的操作。

  2. 叔叔为黑 
    此时较为复杂,分如下四种情况: 
    a)爸爸在左、叔叔在右、我在左 
    title 
    以爸爸为根节点,进行一次R旋转。 
    b)爸爸在左、叔叔在右、我在右 
    title 
    title 
    先以我为根节点,进行一次L旋转; 
    再以我为根节点,进行一次R旋转。 
    c)叔叔在左、爸爸在右、我在左 
    title 
    先以我为根节点,进行一次R旋转; 
    再以我为根节点,进行一次L旋转。 
    d)叔叔在左、爸爸在右、我在右 
    title 
    以爸爸为根节点,进行一次L旋转。

红黑树实际删除节点的性质

  1. 实际删除节点要么是叶子节点,要么有且仅有一个左孩子;
  2. 若为叶子节点,必为红色;
  3. 若实际删除节点还有孩子,则该必为左孩子; 
    a)若左孩子为红色,则实际删除节点必为黑色; 
    b)若左孩子为黑色,则实际删除节点红黑均可以。

约定

  1. 蓝色箭头:表示判定点
  2. 在删除操作开始前,蓝色箭头首先指向实际删除节点。
  3. 『实际删除节点』在图中以『父』表示。

旋转过程开始:

1. 父为红色(待删节点为叶子)

直接删除父节点即可: 
title


2. 父为黑 子为红(待删节点为黑、待删节点子节点为红+左孩子)

用子节点覆盖父节点,并保持父节点的颜色: 
title


3. 父为黑 子为黑(待删节点和子节点均为黑)

3.1. 叔叔为红

PS:叔叔为红,则爷爷必为黑!

  1. 父在左 叔在右 
    a)子节点覆盖父节点 
    b)进行一次左旋 
    title

  2. 父在右 叔在左 
    a)子节点覆盖父节点 
    b)进行一次右旋


3.2. 叔叔为黑

PS:叔叔、爸爸都为黑,那爷爷颜色就不确定了!

  1. 祖父红 两个侄子黑 
    以下两种情况操作一致: 
    1.子覆盖父(删除) 
    2.交换祖父和叔叔的颜色。

    a)父在左 叔在右 
    title 
    b)父在右 叔在左 
    同上。

  2. 祖父黑 两个侄子黑 
    以下两种情况操作一致: 
    1. 祖父染成子节点的颜色; 
    2. 子节点染成黑色; 
    3. 叔叔染成红色 
    a)父在左 叔在右 
    title 
    b)父在右 叔在左

  3. 祖父颜色随意 至少有一个红侄 
    a)红侄为左左(叔左、红侄左) 
    1. 红侄进行一次右旋 
    2. 红侄染成黑色 
    3. 交换叔叔和祖父的颜色 
    title 
    b)红侄为左右(叔左、红侄右) 
    1. 红侄进行一次右旋+左旋 
    2. 红侄染成父节点颜色; 
    3. 父节点染成黑色 
    title 
    c)红侄为右左(叔右、红侄左) 
    1. 红侄进行一次右旋+左旋 
    2. 红侄染成父节点颜色; 
    3. 父节点染成黑色; 
    title 
    d)红侄为右右(叔右、红侄右) 
    1. 红侄进行一次左旋 
    2. 叔叔染成父节点颜色; 
    3. 红侄染成黑色; 
    title

数据结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值