走进数据结构 - 树(Tree)的世界

前言:
        树是各种数据结构中最重头戏的结构。树的各种分类及其子类的各种特征,也是在算法研究和实践中最有价值的学问。本人基于自己的学识和见闻,打算写一篇树的前世今生和树的大家族的介绍,由于自己的各种局限,难免有错误和纰漏,请读者指正,我会一直维护这个文档。

前序:
        数据结构学科告诉我们,dataStructure分为逻辑结构和定义在逻辑上的存储结构。一种数据结构的定义,既可以使用逻辑结构、也可以使用它的实际存储结构去解释。例如一个逻辑上的集合,存储上可以是数组ArrayList,也可以是链表LinkedList,甚至逻辑健全的其他任意存储结构。在不同场景中,也会有不同的封装存储结构,例如使用一个数据结构作为另一个数据结构的一个节点,而达到某些情况下性能更优结构,比如一个node,一个entry等等。
        一个数据结构的衡量指标,也就是一个数据结构的特点,决定着这个结构的定义和存在意义。基于算法标准一个程序的性能就是它这个结构空间和时间的考量。空间上,它元数据本身的存储使用上和计算过程中中间变量(存储)的使用量;时间维度上,对于一个数据结构的经典操作就是对数据的 查询(搜索),写入,修改,删除,等几个操作。
        诚如世间万物,没有一个数据结构在任何使用场景下,都可以表现出最好的性能。但是在大多数场景下都可以表现出不错可用的性能,是开发工程师殚精竭虑要思考和追求的事情。
        如果是一个非常小的数据量,那么你的选择可能就会很多,毕竟小的数据量在强大的计算能力情况下,只要不过分,使用各种数据结构存储和操作之前的差异是非常微小的,也没有太多必要为了很小的数据开辟更多的中间变量和中间操作。毕竟这里面的消耗都是非常微小的,不会有很好的产出。by the way , 一般在实际开发中使用小数据量的情况,往往关注的也不太可能是数据被本身的性能,比如UI编程,更多是别的层面的问题。。在大数据量,或者大并发的情况下,小的差异就会呈现数量级倍的增长,一个非常微小的操作都会被放大几万倍,几亿倍,这种情景下所要思考的问题就更加多,更加底层了。数据结构性能的差异就完全的原型毕露。
        一个大的系统的复杂度,往往不是一个普通人所能理解的,在漫长的使用和发展中,需要融入成千上万上的智慧。在每一个螺丝钉般的岗位上,做好每一个微粒的优化,应用各种测试、弹性和平衡的方法,一个大系统才能生生不息。

1,为什么会有树这种数据结构

    程序=算法+数据结构,这里的数据结构,我们大多数情况下,可以理解为元数据结构。在面向对象的设计时代,数据结构也已经 = 算法+数据结构,这个样子。数据结构越来抽象,结构本身不只是数据实体,而更加是算法本身的空间层面的实现。

2,树的发展历史

    数的发展历史。

3,世面上已经被定义的树类型

节点 node ,根节点 root,叶子节点。树的度,兄弟节点,子孙节点,父节点。

:每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树;

无序树:(自由树)
有序树
二叉树:包含最多两个子节点
满二叉树
平衡树
平衡二叉树,AVL树:最先发明的自平衡二叉查找树算法。
红黑树:自平衡的二叉查找树,1972年由Rudolf Bayer发明的,他称之为"对称二叉B树",它现代的名字是在 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。

  • 性质1. 节点是红色或黑色。
  • 性质2. 根节点是黑色。
  • 性质3 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  • 性质4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

       红黑树为了达到平衡,在插入和移除节点时,需要进行旋转(左旋,右旋),从而再度达到平衡状态。
B树:1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树(或B-树、B_树)

  1. 根结点至少有两个子女;
  2. 每个非根节点所包含的关键字个数 j 满足:┌m/2┐ - 1 <= j <= m - 1;
  3. 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:┌m/2┐ <= k <= m ;
  4. 所有的叶子结点都位于同一层。

B+树:B+树是应文件系统所需而产生的一种B树的变形树。


1、非叶子节点的子树指针与关键字个数相同; 
2、非叶子节点的子树指针p[i],指向关键字值属于[k[i],k[i+1]]的子树.(B树是开区间,也就是说B树不允许关键字重复,B+树允许重复); 
3、为所有叶子节点增加一个链指针; 
4、所有关键字都在叶子节点出现(稠密索引). (且链表中的关键字恰好是有序的); 
5、非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层; 
6、更适合于文件系统;

其他树:
Treap树:二叉排序树
伸展树:Splay Tree,O(log n)内完成插入、查找和删除操作。它由Daniel Sleator和Robert Tarjan创造。它的优势在于不需要记录用于平衡树的冗余信息。在伸展树上的一般操作都基于伸展操作。
SBT:自平衡二叉查找树。中国广东中山纪念中学的陈启峰发明的。陈启峰于2006年底完成论文《Size Balanced Tree》。“目前为止速度最快的高级二叉搜索树”。
 

二叉树
▪ 二叉树 ▪ 二叉查找树 ▪ 笛卡尔树 ▪ Top tree
▪ T树      
 
自平衡二叉查找树
▪ AA树 ▪ AVL树 ▪ 红黑树 ▪ 伸展树
▪ 树堆 ▪ 节点大小平衡树    
 
B树
▪ B树 ▪ B+树 ▪ B*树 ▪ Bx树
▪ UB树 ▪ 2-3树 ▪ 2-3-4树 ▪ (a,b)-树
▪ Dancing tree ▪ H树    
 
Trie
▪ 前缀树 ▪ 后缀树 ▪ 基数树  
 
空间划分树
▪ 四叉树 ▪ 八叉树 ▪ k-d树 ▪ vp-树
▪ R树 ▪ R*树 ▪ R+树 ▪ X树
▪ M树 ▪ 线段树 ▪ 希尔伯特R树 ▪ 优先R树
 
非二叉树
▪ Exponential tree ▪ Fusion tree ▪ 区间树 ▪ PQ tree
▪ Range tree ▪ SPQR tree ▪ Van Emde Boas tree  
 
其他类型
▪  ▪ 散列树 ▪ Finger tree ▪ Metric tree
▪ Cover tree ▪ BK-tree ▪ Doubly-chained tree ▪ iDistance
▪ Link-cut tree ▪ 树状数组  

4,各种树的应用场景

    二叉树遍历:左子树遍历(前序遍历),右子树遍历(后序遍历),中序(中置)遍历。

搜索,排序,存储

5,树对于数据结构优化的意义,及展望

    MySQL数据库索引选择使用B+树。:B/B+树是为了磁盘或其它存储设备而设计的一种平衡多路查找树(相对于二叉,B树每个内节点有多个分支),与红黑树相比,在相同的的节点的情况下,一颗B/B+树的高度远远小于红黑树的高度(在下面B/B+树的性能分析中会提到)。B/B+树上操作的时间通常由存取磁盘的时间和CPU计算时间这两部分构成,而CPU的速度非常快,所以B树的操作效率取决于访问磁盘的次数,关键字总数相同的情况下B树的高度越小,磁盘I/O所花的时间越少。

Java TreeMap,HashMap 用红黑树实现。
 

发布了155 篇原创文章 · 获赞 125 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/u011216417/article/details/81269503