数据结构—查找(Part Ⅱ)—红黑树

红黑树

详细介绍请点击链接

  • 红黑树(Red Black Tree) 是一种自平衡二叉查找树,典型的用途是实现关联数组。
  • 红黑树是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被Leo J. Guibas和Robert Sedgewick修改为如今的“红黑树”。
  • 红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的:它可以在 O ( l o g 2 n ) O(log_2^n) O(log2n)时间内做查找,插入和删除(n是树中元素的数目)。
    点击!平衡二叉树的查找、插入和删除

红黑树的结点类型描述

struct BRnode //红黑树的结点定义
{
	int key; //关键字的值
	RBnode * parent; //父结点指针
	RBnode * lchild; //左孩子指针
	RBnode * rchild; //右孩子指针
	int color; //结点颜色,可用0/1表示黑红,也可以使用枚举类型enum表示颜色
}

红黑树的性质

  • 红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树增加了如下的额外要求:
    性质1:每个结点或是红色或是黑色的。
    性质2:根结点是黑色。
    性质3:所有叶子都是黑色(内部节点、NULL结点、失败结点)。
    性质4:不存在两个相邻的红结点(即红结点的父结点和孩子结点均是黑色的)。
    性质5:对于每个结点,从该结点到任一叶结点的简单路径上,所含黑结点的数目相同。
  • 这些约束强制了红黑树的关键性质:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。
  • 因为红黑树是一种特化的二叉查找树,所以红黑树上的只读操作与普通二叉查找树相同。
  • 红黑树并不是一个完美平衡二叉查找树,它的左右子树高差有可能大于1,从图中可以看到,根结点P的左子树显然比右子树高,但左子树和右子树的黑结点的层数是相等的,也即任意一个结点到到每个叶子结点的路径都包含数量相同的黑结点(性质5)。所以我们叫红黑树这种平衡为黑色完美平衡。

红黑树的左旋、右旋和变色

  • 红黑树依靠三种操作:左旋、右旋和变色能始终保持自平衡。

  • 左旋:以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。

  • 右旋:以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。

  • 变色:结点的颜色由红变黑或由黑变红。

  • 先忽略颜色,可以看到旋转操作不会影响旋转结点的父结点,父结点以上的结构还是保持不变的。

  • 左旋只影响旋转结点和其右子树的结构,把右子树的结点往左子树挪了。

  • 右旋只影响旋转结点和其左子树的结构,把左子树的结点往右子树挪了。

  • 所以旋转操作是局部的。另外可以看出旋转能保持红黑树平衡的一些端详了:当一边子树的结点少了,那么向另外一边子树“借”一些结点;当一边子树的结点多了,那么向另外一边子树“租”一些结点。

红黑树的查找

  • 因为红黑树是一颗二叉平衡树,并且查找不会破坏树的平衡,所以查找跟二叉平衡树的查找无异:
  1. 从根结点开始查找,把根结点设置为当前结点;
  2. 若当前结点为空,返回null;
  3. 若当前结点不为空,用当前结点的key跟查找key作比较;
  4. 若当前结点key等于查找key,那么该key就是查找目标,返回当前结点;
  5. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤2;
  6. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤2;
  • 正由于红黑树总保持黑色完美平衡,所以它的查找最坏时间复杂度为 O ( l o g 2 n ) O(log_2^n) O(log2n),也即整颗树刚好红黑相隔的时候。能有这么好的查找效率得益于红黑树自平衡的特性,而这背后的付出,红黑树的插入操作功不可没。

红黑树的插入

  • 插入操作包括两部分工作:一查找插入的位置;二插入后自平衡。查找插入的父结点很简单,跟查找操作区别不大:
  1. 从根结点开始查找;
  2. 若根结点为空,那么插入结点作为根结点,结束。
  3. 若根结点不为空,那么把根结点作为当前结点;
  4. 若当前结点为null,返回当前结点的父结点,结束。
  5. 若当前结点key等于查找key,那么该key所在结点就是插入结点,更新结点的值,结束。
  6. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤4;
  7. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤4;

  • 情形一&情形二&情形三

  • 情形四:插入结点的父结点为红结点的几种情况

说明调整步骤
情况一叔叔结点存在并且为红结点1. 将“父节点”和“叔叔节点”设为黑色。
2. 将“祖父节点”设为“红色”。
3. 把“祖父节点”设为“当前插入节点”。
情况二"叔叔结点"不存在或为黑结点,并且插入结点的“父结点”是“祖父结点”的左子结点①插入结点是其父结点的左子结点1. 将“父节点”设为黑色。
2. 将“祖父节点”设为“红色”。
3. 对“祖父节点”进行右旋。
②插入结点是其父结点的右子结点1. 对“父节点”进行左旋。
2. 把“父节点”设为“插入结点”。
3. 进行情况二①的处理。
情况三"叔叔结点"不存在或为黑结点,并且插入结点的“父结点”是“祖父结点”的右子结点①插入结点是其父结点的右子结点1. 将“父节点”设为黑色。
2. 将“祖父节点”设为“红色”。
3. 对“祖父节点”进行左旋。
②插入结点是其父结点的左子结点1. 对“父节点”进行右旋。
2. 把“父节点”设为“插入结点”。
3. 进行情况三①的处理。
  • 情况一:

  • 情况二:

  • 情况三:

红黑树的删除

  • 红黑树的删除操作也包括两部分工作:一查找目标结点;而删除后自平衡。查找目标结点显然可以复用查找操作,当不存在目标结点时,忽略本次操作;当存在目标结点时,删除后就得做自平衡处理了。删除了结点后我们还需要找结点来替代删除结点的位置,不然子树跟父辈结点断开了,除非删除结点刚好没子结点,那么就不需要替代。

  • 二叉树删除结点找替代结点有3种情情景:
    情景1:若删除结点无子结点,直接删除
    情景2:若删除结点只有一个子结点,用子结点替换删除结点
    情景3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换删除结点

总结

在这里插入图片描述

BST(二叉排序树)AVL Tree(平衡二叉树)Red-Black Tree(红黑树)
发明时间1960年1962年1972年
时间复杂度Search(查)O(n)O(log₂n)O(log₂n)
Insert(插)O(n)O(log₂n)O(log₂n)
Delete(删)O(n)O(log₂n)O(log₂n)
  • 思考:既然红黑树与二叉平衡树在三种基本操作上的时间复杂度相同,为什么要在二叉平衡树提出的十年后又提出红黑树?
  • 二者的区别:
    平衡二叉树AVL: 插入/删除很容易破坏“平衡”特性,需要频繁调整树的形态。如:插入操作导致不平衡,则需要先计算平衡因子,找到最小不平衡子树(时间开销大),再进行LLI/RR/LR/RL调整。
    红黑树RBT: 插入/删除很多时候不会破坏“红黑”特性,无需频繁调整树的形态。即便需要调整,一般都可以在常数级时间内完成。
  • 二者的适用场景:
    平衡二叉树: 适用于以查为主、很少插入/删除的场景
    红黑树: 适用于频繁插入、删除的场景,实用性更强


红黑树训练题

1.下列选项中,正确的是( )
①红黑树是一种特殊的二叉查找树
②红黑树中的某棵子树(如果有的话),也一定是二叉查找树
③红黑树中的某棵子树(如果有的话),也一定是红黑树
④红黑树中的某棵子树(如果有的话),一定不是红黑树
A.①②
B.①②③
C.①②④
D.①③

  • 红黑树是一种特殊的二叉查找树,满足“左<根<右”的特性。而二叉查找树的定义具有递归特性,其任何一棵子树也是二叉查找树。①②正确
    红黑树中的某棵子树T,若T的根为黑色,则该子树也是红黑树;若T的根为红色,则该子树不是红黑树。③④错误

2.下列选项中,错误的是( )
A.非空红黑树的结点要么是红色,要么是黑色
B.在一棵红黑树中,如果一个结点是黑的,那么它的孩子结点(如果有的话)一定是红的
C.在一棵红黑树中,如果所有结点都是黑的,那么它的形态一定是满二叉树
D.红黑树的查找路径上不允许出现两个连续的红结点

  • A. 红黑树的性质1
  • B. 红黑树中,黑结点的孩子结点可以是红的,也可以是黑的;红结点的孩子结点一定是黑的。
  • C. 如果全部结点都是黑色,那只有满二叉树的形态能满足红黑树的性质5。
  • D. 红黑树的性质4

3.下列选项中,正确的是( )
①若红黑树根结点黑高度为h,则内部结点数(关键字)最少有 2 h − 1 2^h-1 2h1
②若红黑树根节点黑高度为h,则内部结点数(关键字)最多有 2 h − 1 2^h-1 2h1
③包含n个关键字的红黑树,高度不超过 2 l o g 2 n + 1 2log_2^{n+1} 2log2n+1
④红黑树中,红结点的数量不会超过内部结点总数的一半
A.③④
B.①③④
C.④
D.①②③

  • 结点的黑高度是指:从某结点出发(不含该结点)到达任一空叶结点的路径上黑结点总数
    D. 红黑树中,从根结点开始查找,任何一条查找路径上,红结点的数量都不可能超过一半。但是整棵树的红结点总数是有可能过半的

4.下列选项中,错误的是( )
A.红黑树中,任何一个结点的左右子树高度之差不超过2倍
B. AVL树中,任何一个结点的左右子树高度之差不超过1
C.红黑树的查找效率一般要优于AVL树
D.红黑树和AVL树的查找/插入/删除操作的最坏时间复杂度都相同

  • 平衡二叉树适用以查为主的场景
  • 红黑树适用删除、插入的场景

5.下列选项中,错误的是( )
A.对红黑树插入若干关键字,插入次序不同,可能得到不同形态的红黑树
B.对红黑树删除一个关键字,紧接着插入相同的关键字,得到的红黑树可能与原来不同
C.红黑树查找/插入/删除操作的最坏时间复杂度都是 O ( l o g 2 n ) O(log_2^n) O(log2n)
D.红黑树常被用于实现数据库索引

  • B+树常被用于实现数据库索引
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值