5. 数据结构 - 红黑树
这篇文章收录在我的 Github 上 algorithms-tutorial,另外记录了些算法题解,感兴趣的可以看看,转载请注明出处。
(一) 基本概念
Red-Black Tree 称为“红黑树”,是一种自平衡二叉查找树,红黑树和 AVL 树类似,在进行插入和删除时需要通过旋转和重新着色来维持其红黑树的特性。
红黑树的应用相当广泛,主要是用它来存储有序的数据,它的时间复杂度为 O(logn),查询效率非常高。
1. 红黑树和 AVL 树的区别:
- 红黑树并不追求“完全平衡” —— 它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。
- 在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。
- 红黑树的算法时间复杂度和 AVL 相同,但统计性能比 AVL 树更高。
- 红黑树是牺牲了严格的高度平衡的优越条件为代价红黑树能够以 O(log2 n) 的时间复杂度进行搜索、插入、删除操作。由于它的设计,任何不平衡都会在三次旋转之内解决。
2. 红黑树的执行:
- 每个节点具有颜色属性,要么为红色,要么为黑色
- 根节点是黑色的
- 每个叶子节点 (null) 是黑色的 (这里叶子节点,指为空的叶子节点)
- 如果一个节点是红色的,则其子节点必须是黑色的
- 从一个节点到该节点的叶节点 (null) 所有路径包含相同数目的黑节点
3. 红黑树的优点:
- 红黑树的性质决定了从根节点到最远的叶节点的距离不可能超过从根节点到叶节点的距离的两倍。
- 另外可以证明的是红黑树的高度最多为 log(n + 1),n 为节点个数
- 插入和删除在最坏的情况下为 O(logn)
- 红黑树提供了一种替代 AVL 树的方式,并且是一种更加简单,不用递归的插入算法
在查找中,虽然hash表查找非常迅速,但是随着数据的种类增多,
hash表长会变得更长,且冲突也会越来越多,那么如何能实现无论在
多大数据量的情况下,查找依然是高性能的呢?
在1978年,Leo J.Guibas 与 Robert Sedgewick写了一篇论文中
谈到了一种较好的用于查找的数据结构----红黑树
一般来说,树是很好的一种数据结构,那用于插入,删除,查找等
都是很高效的数据树构,但问题是在很坏的情况下,操作很费时间,它的
性能得到不保证,比如二叉查找树中如果左子树与右子树相差太远,那么查找
时就很费时间。这时为了保证其有高效性,就得保证左树与右树不能差得太远,
当向树中插入时,就按一定规则调整,使其达到规则,从而使其整体与局部
查找效率得到提高。这就是红黑树的规则.
这些规则是
在二叉查找树的基础上,
(1)节点都有颜色,要么黑色,要么红色。
(2)根结点是黑色的,叶子结点是黑色的。
(3)每条从树到叶子的路上没有二个连续的红色。即红色的子树一定是黑色
(4)各条从叶子到根的路上的黑色结点相同。
关键的是(3), (4)它使得树是局部是平衡的,并且每条路线不会太长。
还有一个重要的点就是,为了研究方便,会在红黑树补成两个子树是完整的,
它们也有颜色,是黑色,但是没有数据,它称为nil叶子,null叶子。当搜索时
发现结点与nil叶子相 等时,则是找到了叶子了。
另外,关于红黑树与平衡二叉树的区别,它们的区别在概念上也有,
但是在性能上也有,平衡二叉树也是在最坏的情况下有高效的,但是它
追求整体的平衡,使得调整树时,会要很长的时间复杂度,而红黑树是
局部平衡,调整时只要0(logn)颜色变量,并且调整不超过三次。
那么如何使用红黑树来解决问题呢,可以先构造红黑树
构造红黑树的办法如下:
(1)定义节点结构,
一般是 值,key, 长度,左指针,右指针,指向父的指针,颜色。
(2)插入
插入时,先从树根开始,先校验树是不是为空节点或者nil结点,若是
则插入结点为新根,若不是,则与树比较,小于的话,往左移,大于
往右移,这里与二叉查找树类似,最后再对其颜色进行调整.所谓的调
整只有4种情况,都设计好了。
(3)查找
按照二叉查找树的样子进行查找。
例子:查找班上姓名为'