再次去学习红黑树的内容是发现红黑树的奇妙还是超过了以前的发现。
红黑树最神奇的地方在我看来是5点基本定义。这里从来没有包含任何复杂而又高深的数学内容,使用的仅仅是最简单数学原理,没有任何复杂的数学符号。这让我想起了正则表达式和有限自动机的关系,正则表达式是由star,concatenation,和Union三个核心操作就能够组成正则表达式的一切,这三个如此基本的操作与集合论中的操作是一模一样的,是集合论中最基础的数学原理,类比与集合发现正则表达式和集合论的原理是完全类似的。那么红黑树的奇妙之处何在呢?
1. rbt是一种平衡树,它同时支持插入和删除。2. rbt满足5点基本性质。3. 有搜索,插入和删除三个最基本的操作。
对于1:平衡树是用来完成三个功能,在数学上最快的搜索是映射,不过明显在这里并没有应用这个方法。而是使用牛顿用来求函数零点的二分法。虽然说求零点最快的方法是运用数学方法解方程。这点和搜索里面的哈希映射很像,解方程需要大量数学知识,映射也是。同时它们都有其局限性。哈希会让元素之间失去顺序关系,不过也不能排除有不损失元素顺序关系的哈希方法(比如直接哈希,这对内存的消耗简直开玩笑),RBT中核心是二分搜索的原理,但是5大性质中并没有直接提到任何二分有关的东西,跟avl树这样保持左右搜索深度相同这样稍微直观的搜索树不一样。RBT对这个原理的应用体现在什么地方呢?
如何每一步操作都尽量减半搜索规模呢? 理论最好的方法很是直观,就是每次比较都能减半搜索规模,这就是最好的二分方法。不过就像排序算法一样,虽然理论最好的比较排序算法是O(log(n!))但是没听说过谁能不付出其它的代价而做到的象后面的所说的RBT树一样。所以只能使用一些近似减半的搜素策略,
比如每一个节点的左右子树深度相同这样的idea(AVL),在搜索和插入和删除操作直接的平衡性做的当时很好,或许搜索时间和插入以及删除的时间之间的方差会比较小吧,左右节点深度相同这样的idea到底有多近似于完美的搜索树并不清楚。
在比如SBT平衡树,虽然不知道是怎么回事,但是应该是通过保持树节点左右两端节点数量尽可能一致的方法来减半搜索规模,这样也存在问题,这种树应该是去不断寻找一个尽可能使得左右子树平衡的节点为每个子树的根节点,这样做应该可以在搜索速度上保持觉得优势,但是对于插入和删除操作会有严重后果,维护时间应该是十分不理想吧,因为和avl以及RBT不一样的是一旦添加或者删除某一个节点,那么SBT应该从这个节点开始到根节点每一个节点都会发生改变,这在avl和rbt中只有在很小的概率才会发生的事情而在RBT中每次都会发生,不过应该也有提升的算法,如果平均维护一次树需要N的时间那么就容许树的左右节点有一定的大小差距,这个差距造成平均搜索时间和维护搜索树的实现N一样的时候在去维护,其实也就是不是每一次插入和删除都去维护这个RBT,只有忍无可忍才去维护。不过这样应该又会出现别的问题,但和红黑树相比感觉还是开销大了点,没有具体实现的代码也没法去细致的比较。
在比如树堆则使用了随机数原理,通过一个随机数的优先级来确定谁在上面谁在下面,在总体上看是很平均的,不过对于某些一旦建立树就长时间使用的树来说如果一开始选错了就会造成不好的结果,不过也可以根据数据信息通过实际使用经验中信息来做一些启发式的优先级的设定,或许也能做的很好。
这几个idea都很具有创意,而且相对直观就能看出来它能做的很好,它们(包括红黑树)的共同特点是都在数据上附加额外信息,并且为这个信息建立维护的规则。
红黑树和AVL树一样,是从树的深度这个角度考虑问题,但是效果上确接近于二分方法。不过和avl树的目的是在考虑缩小搜索深度,而不是考虑减半搜索规模,这是换了个角度在看待问题,当搜索深度达到最小的时候,同时也是接近完美的减半搜索规模。与avl只在乎左右深度相同的做法不同,RBT在乎的是每一条到叶节点的路线的长度,它的搜索深度的方差应该是比avl更为稳定的,因为黑高相同,一条根叶路线上红色节点数量小于等于黑色节点,那么可以知道最大深度为两倍黑高,最低深度为一倍黑高。算法导论上数学证明最深为2lg(n+1)。
通过这里想到一个问题:我也从树深的角度上来考虑问题。如果我们建立一个这样的搜索树称为X-Tree,它的根节点(对于非根节点可以不满足这样性质)到任意一个空节点(null节点,而不是叶节点)的最大深度和最小深度差距恒小于log(n+1);n为总结点数目。这样一个搜索树数据结构需记录到这个字树中空节点的最大和最小的距离,但是在最差情况下的搜索效率还会高于avl树,因为最大树深和最小树深差距恒小于log(n+1),而如果最大树深度超过RBT的2*log(n+1)的话,那么根到null节点的最小距离大于log(n+1),这个是不可能的,因为低于最低的根到null节点的距离的部分是满二叉树,而,log(n+1)深度的满二叉树的节点数量是n个,但又存在2*log(n+1)这样深度的分支,故而这样的树在最差情况的搜索深度是小于RBT的。在对插入和删除问题上如果插入后如果导致树根到null的最大深度减去最小深度大于log(n+1)那么就不断从插入的节点向上走直到它的某一个祖先的节点的旋转可以满足条件为止,这时候只要旋转一次就行,而RBT可能要进行多次旋转。删除也是同样,所以插入和删除可以共用维护用的代码。这样的树只有在对付完全顺序插入的时候情况会变得最差,会导致最大到空节点深度和最小到空节点深度等于log(n+1),不过由于很多时候插入和删除的维护工作部分什么都不用做,相比于红黑树而言插入和删除的效率更高。问题在于红黑树在面对顺序插入时候是否做的比这个X-Tree好呢?。懒的去管。回来比较X-Tree和RBT之间,RBT用黑深度来约束最大和最小搜索长度。而所谓的X-Tree是用跟到任意一个空节点最短和最大之差来约束搜索深度,比较可以发现,由于X-Tree的idea包含了最大根节点到空节点的距离为2 * log(n+1)。不过红黑树还包括了红色节点,事实上RBT的深度方差应该会小于X-Tree,不过X-Tree的约束用的深度差确实任意的,如果让深度差为1的话,就是一棵完全二叉树,虽然这样会造成插入和删除操作需要更多的工作。虽然在维护细节上好像还存在bug,不过我这里无所谓,维护性质的方法总是存在的,如何插入,如何删除,基本也要耗去log(n)的时间。惨不忍睹。