1、二叉查找树(BST)
又称:排序二叉树、二叉搜索树、二叉排序树
特点:左结点 <= 根结点 <= 右结点
查找代价:最差情况和顺序查找效率相同。造成这种情况的主要原因就是BST不够平衡(左右子树高度差太大)
总结:
平均时间复杂度O(logN),最坏时间复杂度O(N)
插入删除操作算法简单,时间复杂度与查找差不多
2、平衡二叉树(AVL)
改进二叉查找树,将不平衡树改成平衡二叉树
特点:1、左右子树都为AVL
2、左右子树高度差不能超过1
查找代价:查找过程与BST一样,只是不会出现BST最差情况(单支树)。
总结:
查找的时间复杂度维持在O(logN),不会出现最差情况
每个插入操作时最多需要1次旋转,其时间复杂度在O(logN)左右
删除时代价稍大,执行每个删除操作的时间复杂度需要O(2logN)
3、红黑树(RBT)
AVL的严格平衡策略是牺牲插入、删除操作(建立查找结构)为代价换来稳定的查找效率O(logN)
RBT的策略:即不牺牲太大的建立查找结构的代价,也能保证稳定高效的查找效率。
特点:
1、每个节点要么是红色要么是黑色
2、根结点永远是黑色
3、所有叶子节点都是空节点,并且是黑色的。
4、每个红色节点的两个子节点都是黑色。(从每个叶子到根的路径上不会有两个连续的红色节点)
5、从任何一个节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。
红黑树并不追求“完全平衡”,它只要求部分地达到平衡要求,降低了旋转的要求,从而提高了性能。
任何不平衡都会在三次旋转之内解决,红黑树能够以O(logN) 的时间复杂度进行搜索、插入、删除操作。
如果数据是静态的,哈希表的性能会高于红黑树。
4、B树/B+树
对于在内存中的查找而言,红黑树的效率已经很好了,但是如果是数据量非常大的查找呢?将这些数据全部放入内存中显然不太合适。事实上,像文件目录存储、数据库文件索引结构存储都不可能在内存中查找结构,必须在磁盘中建立好这个结构。
在磁盘中组织查找结构,从任何一个结点指向其他结点都有可能读取一次磁盘数据,再将数据写入内存进行比较。由于磁盘IO慢,所有的二叉树查找结构在磁盘中都是低效的。
B树就是用来解决这个问题的,其实质上是一个平衡的多路查找树
B树的查找分为两种:
1、从一个结点查找到另一结点的地址时,直接定位磁盘地址。
2、另一种是将结点中的有序关键字序列放入内存,进行查找,由于B树的高度很小,因此在这一背景下,B树比任何二叉树结构查找树的效率都高的多。
B-Tree效率总结: 由于考虑磁盘储存结构,B树的查找、删除、插入的代价都远远要小于任何二叉结构树(读写磁盘次数的降低)
5、伸展树
基本思路:在使用二叉树进行一系列查找操作时,为了使整个查找时间最小,被查频率高的那些条目就应当经常处于靠近树根的位置。所以每次查找之后对树进行重构,把查找的结果挪到最靠近树根的地方。(不需要记录平衡的冗余信息)
伸展树使用“自我调节”的数据结构,时间复杂度比较低,各种基本操作的平均时间复杂度为O(logN)
由于不需要存储冗余信息,所以其所需的存储空间更小,一系列查找操作中某一个可能会耗时较长,这在实时应用程序中可能是一个不足之处。
6、Tire(前缀树/字典树)
是一种有序多路树,用于保存关联数组。与二叉查找树不同的是,键不是直接保存在节点中的,而是由节点在树中的位置决定的,一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。
从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
优点:可以最大限度地减少无所谓的字符串比较,故可以用于词频统计和大量字符串排序。
跟hash表比较:不存在冲突,自带排序功能,先序遍历可以得到字典排序。
缺点:虽然trie不同单词共享前缀,但其实是一个以空间换时间的算法,其中每一个字符都可能包含最多字符集大小数据的指针。而且如果数据存储在外部存储器等较慢的位置,Trie会比hash慢
应用场景:字符串检索、词频统计、拼写检查、排序、字符串公共前缀
最大限度地减少无谓的字符串比较,查询效率比哈希表高。Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
参考: