树的表示方法
- 直观表示法
树的直观表示法就是以倒着的分支树的形式表示,如下图所示就是一棵树的直观表示。其特点就是对树的逻辑结构的描述非常直观,是数据结构中最常用的树的描述方法
文章图片
- 嵌套集合表示法
所谓嵌套集合是指一些集合的集体,对于其中任何的两个集合,或者不相交,或者一个包含另一个。用嵌套集合的形式表示树,就是将根节点视为一个大的集合,其若干棵子树构成这个大集合中若干个互不相交的子集,如此嵌套下去,即构成一棵树的嵌套集合表示。如下图所示
文章图片
- 凹入表示法
主要用于树的屏幕输出和打印输出
文章图片
- 广义表表示法
树用广义表表示,就是将根作为由子树森林组成的表的名字写在表的左边,这样一次将树表示出来。如下所示
(A(B(D,E(H,I),F),C)G)))
- 结点
表示树中的元素,包括数据项及若干指向其子树的分支
- 结点的度
结点所拥有的子树的个数称为该结点的度
- 叶子结点
度为0的结点称为叶子结点,或者称为终端结点
- 分支结点
度不为0的结点称为分支结点,或者称为非终端结点。一棵树的结点除叶子结点外,其余的都是分支结点
- 孩子、双亲、兄弟
若在一棵树中一个结点A的子树的根节点是B,则称B为A的孩子,称A为B的双亲。具有同一个双亲的子结点互称为兄弟
- 路径、路径长度
如果一棵树的一串结点$n_1,n_2,...n_k$有如下关系,即结点$n_i$是$n_{i+1}$的父结点(1<=i - 祖先、子孙
如果有一条路径从结点M到结点N,那么M就称为N的祖先,而N称为M的子孙
- 结点的层数
规定树的根节点的层树为1,其余结点的层树等于它的双亲结点的层树加1
- 树的深度
树中所有结点的最大层树称为树的深度
- 树的度
树中各结点度的最大值称为该树的度
- 有序树和无序树
如果一棵树中结点的各子树从左到右是有次序的即若交换了某结点各子树的相对位置,则构成不同的树,称这棵树为有序树,反之称为无序树
- 森林
零棵或有限棵不相交的树的集合称为森林。自然界中树和森林是不同的概念。在数据结构中,树和森林只有很小的差别,任何一棵树,删去根节点就变成了森林
二叉树是指树中节点的度不超过2的有序树。二叉树的递归定义可以为一棵空树,或者一个有根节点和两棵互不相交的,分别称为根的左子树和右子树组成的非空树,左子树右子树又同样是二叉树。
二叉树是递归定义的,节点上有左右子树之分,逻辑上二叉树有五种基本形态
基本形态
- 空树(图-a)
- 只有一个根节点的二叉树(图-b)
- 只有左子树(图-c)
- 只有右子树(图-d)
- 完全二叉树(图-e)
文章图片
- 满二叉树
深度为k,且有 $2^k -1$ 个节点的树称为满二叉树
满二叉树定义,每一层上的所有节点都有两个子节点,也即是倒数第二层的所有节点都有两个子节点,那么最后一层的所有节点数一定是倒数第二层的2倍,所以最后一层一个节点都不能缺
文章图片
- 完全二叉树
深度为k,有n个节点的二叉树当且仅当每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完成二叉树
叶子节点只能出现在最下层或者次下层,且最下层的节点集中在树的左侧,满二叉树肯定是完全二叉树,完全二叉树不一定是满二叉树
文章图片
文章图片
文章图片
- 性质1 一棵非空二叉树的第i层上最多有 $2^{i-1}$ 个结点(i>=1)
在图1
中,第4层的结点正好为$2^{4-1}=8$个结点
- 性质2 一棵深度为k的二叉树中,最多具有$2^k-1$个结点
在图1
中,二叉树的深度为4,正好拥有$2^4-1=15$个结点
- 性质3 对于一棵非空的二叉树,如果叶子结点数为$n_0$,度数为2的结点数为$n_2$,则有$n_0=n_2+1$
在图1
中,二叉树的叶子结点有:H,I,J,K,L,M,N,O共8个结点,而度数为2的结点有:A,B,C,D,E,F,G,共7个结点
- 性质4 具有n个结点的完全二叉树的深度k为$log2^n+1$
在图2
中,共有10个结点,其深度正好是$log_2{10}+1=4$
- 性质5 对于具有n个结点的完全二叉树,如果按照从上至下,从左到右的顺序对二叉树中的所有结点从1开始进行顺序编号,则对于任意的序号为i的结点,有:
- 如果
i>1
,则序号为i
的结点的父结点的序号为i/2
; 如果i=1
,则该结点是根节点,无父结点 - 如果
2i<=n
,则序号为i
的结点的左子结点的序号为2i
;如果2i>n
,则序号为i
的结点无左子结点 - 如果
2i+1<=n
,则序号为i
的结点的右子结点的序号为2i+1
;如果2i+1>n
,则序号为i
的结点无右子结点
图2
理解
- 如果
文章图片
以上图二叉树为例,三种遍历方式结果如下
先序遍历(DLR)
- 访问根节点
- 先序遍历根结点的左子树
- 先序遍历根结点的右子树
ABDC
中序遍历(LDR)
- 中序遍历根结点的左子树
- 访问根结点
- 中序遍历根结点的右子树
BDAC
后序遍历(LRD)
- 后序遍历根结点的左子树
- 后序遍历根结点的右子树
- 访问根结点
DBCA
B树 定义
B树也成多路平衡查找树,我们描述一棵B树的时候一般指定它的阶数,阶数表示一个结点最多有多少个孩子结点,一般用字母m表示阶数,当 m=2,也就是我们说的二叉查找树
一棵m阶的B树定义如下:
- 树中每个结点最多有m棵子树
- 若根结点不是叶子结点,则至少有两棵子树
- 除根之外的所有非叶子结点至少有[m/2]棵子树
- 所有的非叶子结点包含下列信息数据($n,p_0,k_1,p_1,p_2,...,k_n,p_n$),$k_i$是关键字,且$k_i$<$k_{i+1}$,$p_i$为指向子树根结点的指针,且$p_i$所指向子树中所有结点的关键字均小于$k_{i+1}$,$p_i$为指向根结点的指针,且$p_i$所指子树中所有节点的关键字均小于$k_{i+1}$且大于$k_i$,n为关键字的个数
- 所有的叶子结点都出现在同一层次上,根结点到每个叶子结点的长度一致
B树的变形树,B+树上的叶子结点存储关键字以及相应记录的地址,叶子结点以上各层作为索引使用,一棵m阶的B+树定义如下
- 每个结点最多有m个子女
- 除根结点外,每个结点至少有[m/2]个子女,根结点至少有2个子女
- 有k个子女的节点必有k个关键字
下面是B树结构的演示视频
- 【100,200,300,400,500,600,700,800,900】插入流程
- 500的查询
- 400的删除
B树与B+树对比
- B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针,所以其内部结点相对B树更小,如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,。相对来说IO读写次数也就降低了,查找速度更快了
- B+树查询效率更稳定
由于非叶子结点并不是最终指向文件内容的结点,而只是叶子结点关键字的索引。所以B+树中任何关键字的查找必须走一条从根结点到叶子结点的路,所有关键字查询的路径长度相同,导致每一个数据的查询效率相当,而对于B树来说,因为每个结点都存有具体的数据,因此其查询速度不稳定,可能很快也可能很慢。
- B+树便于范围查询
B树在提高了IO性能的同时,并没有解决元素遍历效率低下的问题。为了解决这个问题,B+树应运而生。B+树只需要遍历叶子结点就可以实现整棵树的遍历(B+树叶子结点维护有序链表。在数据库中基于范围的查找也是非常频繁的,因此MySQL的Innodb引擎就使用了B+树作为其索引的数据结构
- 【100,200,300,400,500,600,700,800,900】插入流程
- 500的查询
- 400的删除
红黑树是一种特定类型的二叉树,它是在计算机科学中用来组织数据比如数字的块的一种结构
红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低,其平均统计性能要强于AVL
由于每一棵红黑树都是一棵二叉排序树,因此,在对红黑树进行查找时,可以采用运用于普通二叉树上的查找算法,在查找过程中 不需要颜色信息
性质
- 结点是红色或黑色
- 根结点是黑色
- 所有叶子都是黑色(叶子是NIL结点)
- 每个红色结点的两个字结点都是黑色(从每个叶子到根的所有路径上不能由两个连续的红色的结点)
- 从任一结点到其每个叶子的所有路径都包含相同数据的黑色结点
- 【100,200,300,400,500,600,700,800,900】插入流程
- 500的查询
- 400的删除
【树【二叉树,红黑树,B树,B+树】】原文链接
推荐阅读
- java|vue - ES6模块化、promise、webpack打包(所在在学的朋友们先看这篇,看了不吃亏)...
- java|日撸代码300行(第52天(kNN分类器续))
- Java|社招和校招有什么不同(阿里美团等大厂 JAVA 社招面经分享)
- Java学习|[Java] 弄懂数组,这一篇就够了
- java毕设系列|基于SSM的水果商城(免费源码获取+运行指导+论文)
- Java编程|【java篇】java中数组到底是不是对象()
- nginx|Nginx学习笔记(五)(浅析Nginx原理)
- #|《实战 Java 高并发程序设计》笔记——第4章 锁的优化及注意事项(一)
- Java业务开发常见错误100例(代码篇-1)