“If I have seen further it is by standing on the shoulders of giants.”

——Issac Newton

树的种类1

1.无序树

树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树


2. 有序树

树中任意节点的子节点之间有顺序关系,这种树称为有序树

下面所说的树均为有序树。


2.1 完全二叉树

二叉树:每个节点最多含有两个子树的树称为二叉树。

完全二叉树:对于一棵二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树。

满二叉树:所有叶节点都在最底层的完全二叉树。满二叉树是特殊的完全二叉树。


2.2 平衡二叉树

平衡二叉树(AVL树):当且仅当任何节点的两棵子树的高度差不大于1的二叉树。


2.3 排序二叉树

排序二叉树(二叉查找树(英语:Binary Search Tree)):也称二叉搜索树、有序二叉树


2.4 哈夫曼树

哈夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树;


2.5 B树

B树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多于两个子树



完全二叉树

完全二叉树:在一颗二叉树中,若除最后一层外的其余层都是满的,并且最后一层要么是满的,要么在右边缺少连续若干节点,则此二叉树为完全二叉树(Complete Binary Tree)。
完全二叉树
上图来源于:百度百科完全二叉树

具有 n n n 个节点的完全二叉树的深度为 l o g 2 n + 1 log_2n+1 log2n+1

深度为 k k k 的完全二叉树,至少有 2 k − 1 2^{k-1} 2k1 个节点,至多有 2 k − 1 2^k-1 2k1 个节点。

满二叉树
所有叶节点都在最底层的完全二叉树。
满二叉树
上图源自于:https://icode.best/i/47521033483510



平衡二叉树

在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为高度平衡树。
平衡二叉树
上图来源于:http://kpali.me/2018/12/24/data-structure-and-algorithm-balanced-binary-tree.html

左图为平衡二叉树,而右图不是平衡二叉树,具体详解我觉得这个博客说的很好,可以查看:http://kpali.me/2018/12/24/data-structure-and-algorithm-balanced-binary-tree.html

平衡因子:节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子10-1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。


非平衡二叉树的AVL旋转

AVL树的基本操作一般涉及运作同在不平衡的二叉查找树所运作的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL旋转"。

假设平衡因子是左子树的高度减去右子树的高度所得到的值,又假设由于在二叉排序树上插入节点而失去平衡的最小子树根节点为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先节点),则失去平衡后进行的规律可归纳为下列四种情况2

  1. 单向右旋平衡处理LL:由于在a的左子树根节点的左子树上插入节点,a的平衡因子由1增至2,致使以a为根的子树失去平衡,则需进行一次右旋转操作;
  2. 单向左旋平衡处理RR:由于在a的右子树根节点的右子树上插入节点,a的平衡因子由-1变为-2,致使以a为根的子树失去平衡,则需进行一次左旋转操作;
  3. 双向旋转(先左后右)平衡处理LR:由于在a的左子树根节点的右子树上插入节点,a的平衡因子由1增至2,致使以a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操作。
  4. 双向旋转(先右后左)平衡处理RL:由于在a的右子树根节点的左子树上插入节点,a的平衡因子由-1变为-2,致使以a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操作。
    AVL旋转
    上图来源于:https://zh.wikipedia.org/wiki/AVL%E6%A0%91#/media/File:AVL_Tree_Example.gif


排序二叉树

二叉查找树(英语:Binary Search Tree),也称为二叉查找树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
    二叉排序树


哈夫曼树

哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为 W P L = ( W 1 × L 1 + W 2 × L 2 + W 3 × L 3 + . . . + W n × L n ) WPL=(W_1\times L_1+W_2\times L_2+W_3\times L_3+...+W_n\times L_n) WPL=(W1×L1+W2×L2+W3×L3+...+Wn×Ln),N个权值 W i ( i = 1 , 2 , . . . n ) W_i(i=1,2,...n) Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为 L i ( i = 1 , 2 , . . . n ) L_i(i=1,2,...n) Li(i=1,2,...n)。可以证明霍夫曼树的 W P L WPL WPL是最小的3
哈夫曼树
上图来源于:https://blog.csdn.net/qq_29519041/article/details/81428934

对于哈夫曼树的构造这篇博客很详细:https://blog.csdn.net/qq_29519041/article/details/81428934



B树

B树(英语:B-tree)是一种自平衡的树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。B树,概括来说是一个一般化的二叉查找树(binary search tree)一个节点可以拥有2个以上的子节点。与自平衡二叉查找树不同,B树适用于读写相对大的数据块的存储系统,例如磁盘。B树减少定位记录时所经历的中间过程,从而加快存取速度。B树这种数据结构可以用来描述外部存储。这种数据结构常被应用在数据库和文件系统的实现上4
B树
上图来源于:https://zhuanlan.zhihu.com/p/27700617

(1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;

(2)子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);

(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);

(4)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子5;

关于B树和B+树的插入、删除图文详解,可以查看这篇博客:https://www.cnblogs.com/nullzx/p/8729425.html



红黑树

关键就是这五个性质深入理解,然后其他的就跟平衡二叉树近似,因为并没有对平衡因子的要求。

  • 性质1:每个节点要么是黑色,要么是红色。
  • 性质2:根节点是黑色。
  • 性质3:每个叶子节点(NIL)是黑色。
  • 性质4:每个红色结点的两个子结点一定都是黑色。
  • 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

关于很详细的红黑树解释可以看这篇博客:https://www.jianshu.com/p/e136ec79235c



致谢

再次感谢被本文引用的文章作者,以及对本文有贡献的所有作者,谢谢!


  1. 维基百科 树_(数据结构) ↩︎

  2. 维基百科 AVL树 ↩︎

  3. 维基百科 霍夫曼编码 ↩︎

  4. 维基百科 B树 ↩︎

  5. 知乎 平衡二叉树、B树、B+树、B*树 理解其中一种你就都明白了 ↩︎

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐