龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

数据结构之红黑树详解

时间:2014-08-30 02:22来源:网络整理 作者:网络 点击:
分享到:
这篇文章主要介绍了数据结构之红黑树详解,红黑树是一种自平衡二叉查找树,它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用,需要的朋友可以参考下

1.简介

红黑树是一种自平衡二叉查找树。它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除等操作。

本文介绍了红黑树的基本性质和基本操作。

2.红黑树的性质

红黑树,顾名思义,通过红黑两种颜色域保证树的高度近似平衡。它的每个节点是一个五元组:color(颜色),key(数据),left(左孩子),right(右孩子)和p(父节点)。

红黑树的定义也是它的性质,有以下五条:

性质1. 节点是红色或黑色

性质2. 根是黑色

性质3. 所有叶子都是黑色(叶子是NIL节点)

性质4. 如果一个节点是红的,则它的两个儿子都是黑的

性质5. 从任一节点到其叶子的所有简单路径都包含相同数目的黑色节点。

这五个性质强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。为什么呢?性质4暗示着任何一个简单路径上不能有两个毗连的红色节点,这样,最短的可能路径全是黑色节点,最长的可能路径有交替的红色和黑色节点。同时根据性质5知道:所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。

3.红黑树的基本操作

因为红黑树也是二叉查找树,因此红黑树上的查找操作与普通二叉查找树上的查找操作相同。然而,红黑树上的插入操作和删除操作会导致不再符合红黑树的性质。恢复红黑树的性质需要少量(O(log n))的颜色变更(实际是非常快速的)和不超过三次树旋转(对于插入操作是两次)。虽然插入和删除很复杂,但操作时间仍可以保持为 O(log n) 次。

3.1插入操作

插入操作可以概括为以下几个步骤:

(1)查找要插入的位置,时间复杂度为:O(N)

(2)将新节点的color赋为红色

(3)自下而上重新调整该树为红黑树

其中,第(1)步的查找方法跟普通二叉查找树一样,第(2)步之所以将新插入的节点的颜色赋为红色,是因为:如果设为黑色,就会导致根到叶子的路径上有一条路上,多一个额外的黑节点,这个是很难调整的。但是设为红色节点后,可能会导致出现两个连续红色节点的冲突,那么可以通过颜色调换(color flips)和树旋转来调整,这样简单多了。下面讨论步骤(3)的一些细节:

设要插入的节点为N,其父节点为P,其父亲G的兄弟节点为U(即P和U是同一个节点的两个子节点)。

[1] 如果P是黑色的,则整棵树不必调整便是红黑树。

[2] 如果P是红色的(可知,其父节点G一定是黑色的),则插入z后,违背了性质4,需要进行调整。调整时分以下3种情况:

(a)N的叔叔U是红色的

如上图所示,我们将P和U重绘为黑色并重绘节点G为红色(用来保持性质5)。现在新节点N有了一个黑色的父节点P,因为通过父节点P或叔父节点U的任何路径都必定通过祖父节点G,在这些路径上的黑节点数目没有改变。但是,红色的祖父节点G的父节点也有可能是红色的,这就违反了性质4。为了解决这个问题,我们在祖父节点G上递归调整颜色。

(b)N的叔叔U是黑色的,且N是右孩子

如上图所示,我们对P进行一次左旋转调换新节点和其父节点的角色; 接着,按情形(c)处理以前的父节点P以解决仍然失效的性质4。

(c)N的叔叔U是黑色的,且N是左孩子

如上图所示,对祖父节点G 的一次右旋转; 在旋转产生的树中,以前的父节点P现在是新节点N和以前的祖父节点G 的父节点, 然后交换以前的父节点P和祖父节点G的颜色,结果的树满足性质4,同时性质5[4]也仍然保持满足。

3.2删除操作

删除操作可以概括为以下几个步骤:

(1)查找要删除位置,时间复杂度为:O(N)

精彩图集

赞助商链接