前言:
PS:01Trie严格上不算是一种平衡树,只是能解决普通平衡树问题,所以放在了这里。
本来没想着一个平衡树学两三周这么长时间的,不过感觉还挺有趣的就是了(虽然卡主的时候非常痛苦就是了,但是debug出来的时候也很爽就是了)。让我对平衡树,树,树上的递归有了比较深的理解,提高了代码能力(大概),总结了二叉平衡树的一个大概的实现范式。
我觉得平衡树的性能大概可以从实现难度,拓展性和基本功能效率(指search,erase,insert三者)三个方面考量。
下面三个方面纯主观评价:
实现难度: B > RB > AVL > Splay > 带旋Treap≈无旋fhq-Treap。
B树我觉得是最难的,没有之一,可能是因为B树是多叉树导致的,而且清晰的教程比较少,我在写的时候也没找到数据结构可视化的网站(Data Structure Visualization (usfca.edu) ) 实现的时候真的痛苦至极,删除策略真的很要人命。之后的红黑树,其实在有AVL树基础的时候容易理解了很多,只是红黑树的几个性质不是非常好理解。AVL树比较难主要是因为这是我第一个接触的旋转平衡树,所以耗的时间比较长。后面三个真的很简单,基本上没难度,代码也非常短。
拓展性:带旋Treap≈无旋fhq-Treap≈Splay > AVL≈RB > B
这是平衡条件所决定的,平衡条件越苛刻,效率越高,拓展性越差。
基本功能效率:RB≈AVL > 带旋Treap > 无旋Treap≈Splay > B
RB和AVL平衡条件苛刻,基本效率比较高;Treap因为随机的原因趋于平衡;Splay效率说实话比较随缘;B树如果找不到一个合适的阶数效率不高。
所以考虑基本功能效率的话就是RB和AVL,这两者再考虑实现难度的话,首推AVL树;考虑有比较好的效率的同时有很好的拓展性,就是Splay,无旋fhq-Treap,带旋Treap,再考虑实现难度,还是推荐无旋fhq-Treap。
关于旋转,我觉得对于Treap,Splay,RB,AVL来说,旋转有着各自不同的含义,很有趣,在不同方面都有应用吧(大概,纯主观。)
AVL树是平衡树的始祖,旋转主要是最基本的降低左右子树高度差的同时保持二叉排序树的性质,搜索的效率最高。 如果是自用的话,搓一个AVL树的模板,效率一点不比stl红黑树map差。
RB在AVL基础上看到了旋转的父亲兄弟节点位置的变化,借由染色操作,模拟4阶B树,实现了搜索,插入,删除的综合,应用范围最广,stl中map和set就是红黑树,所以只需要重载小于符就能用。
Splay侧重于旋转对于一个孩子节点来说可以实现位置的抬高,一步一步实现节点到达根。(或许在缓存方面会有应用?)
Treap侧重于旋转对于一个父亲节点来说可以实现位置的降低,这让它实现了fix值的堆性质。又因为随机数的原因,让它不容易被卡,所以竞赛常见。
想法:有趣,快学。
再次感谢 zno zno B站AgOH大佬 orz orz。
B-树:
B-树 全代码实现 算是半自主研发了吧(雾) 以洛谷P1177桶排验证-CSDN博客
AVL树:
AVL树 全代码实现 用洛谷P3369 P1177验证-CSDN博客
RB树:
带旋Treap:
无旋fhq-Treap
Splay树:
01Trie树:
包括从高位开始和从低位开始两种思路。