你了解红黑树吗?数据结构——红黑树

红黑树:


引言

因为博主最近在学习HashMap的源码,因为自从jdk1.8之后,HashMap就是由数组+链表+红黑树实现的,所以为了更深的去了解HashMap的原理,先来带大家一起复习一下红黑树的知识


红黑树的介绍

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


红黑树的五条性质

红黑树是一个平衡二叉树,但不是绝对完美的平衡二叉树,红黑树是在普通的二叉树上,加了一个颜色的属性所构成的,整个红黑树需要满足以下五条性质:

  1. 节点是红色或黑色。
  2. 根节点是黑色。
  3. 所有叶子节点都是黑色。(叶子是NUIL节点)
  4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点,并没有说不能出现连续的黑色节点
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树的关键操作

瞬间懵逼?了解一下印象就行,开始玩魔方都是要照着魔方公式一点点玩的,多玩几次就熟悉了。红黑树也一样,红黑树有两大操作:

  1. recolor (重新标记黑色或红色)
  2. rotation (旋转,从而使树达到平衡)
    我们会先尝试 recolor,如果 recolor 不能达到红黑树的 4 点要求,然后我们尝试 rotation,其实红黑树的关键玩法就是弄清楚 recolor 和 rotation 的规则

因为当你对红黑树进行新增或者删除操作的时候,对树做的修改可能会破坏红黑树的性质。为了继续保持红黑树的性质,可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即通过修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后继续保持它的性质或平衡的目的。

红黑树的旋转

首先我们来介绍一下红黑树的旋转操作,红黑树有个特点,新增的节点默认为红色,且左边的节点永远小于右边的节点,比如:
红黑树1

这里是一个红黑树,当你从数轴的左侧往右侧看的时候,它在横轴上的投影永远都是从左向右依次递增的。

然后我们由一棵根节点为10的红黑树开始逐步讲解
红黑树2

正常插入节点

首先我们插入5这个节点,因为5小于10,所以直接将5插入成为10的左节点
红黑树3

当你要在插入一个大小为4的节点,由于4小于10,所以向10的左子树看,4又小于5,所以再看向5的左子树,此时5的下方只有叶子节点(NUIL),所以4成为了5的左节点:
红黑树

红黑树的变色

此时并没有结束,因为红黑树要求不可以有两个连续的红色节点,否则就违反了性质4,所以我们要对节点进行变色处理,将4的父节点5变为黑色

红黑树的旋转

然而此时红黑树就不再平衡,为了使红黑树再次平衡,此时我们的旋转就出场了,红黑树的旋转遵循一个原则“父母围着孩子转”,也就是说父节点绕着子节点进行旋转,旋转方向分为左旋转和右旋转,具体方向依照节点的大小决定。

1.右旋转

此时由于4小于5,10又大于5,所以按照规则,5的父节点,也就是10,向右做旋转操作(因为父节点大于子节点),成为了5的右节点
右旋转

2.左旋转

对于这样的一棵红黑树
左旋转
当我们插入一个50的节点的时候,
首先找到5,50>5,然后向右,找到10,50>10,再向右找到20,50>20,则再向右发现只有叶子节点(NUIL),则成为了20的右节点
在这里插入图片描述
由于此时又出现了两个连续的红色节点,所以进行变色处理,依次向上递归变色,首先将20变为黑色,然后发现20的父节点小于20,为了平衡红黑树,所以我们进行左旋转处理(因为父节点小于子节点),即10成为了20的左节点,并且变为红色
在这里插入图片描述
这里就是红黑树的变色与旋转操作
下一步就是对HashMap源码的讲解,请大家敬请期待!

猜你喜欢

转载自blog.csdn.net/u013523775/article/details/108458578