联系我们:有道技术团队助手:ydtech01 / 邮箱:[email protected].com
前言
树形结构,尤其是二叉树,在我们平时开发过程中使用频率比较高,但之前对于树形结构没有一个比较系统全面的了解和认知,所以借此机会梳理一下。
本文属于《你真的了解二叉树吗》系列文章之一,主要介绍的是树形结构的基础,在看完这篇文章之后,如果想要更加熟练掌握二叉树的话,可以看另一篇《你真的了解二叉树吗(手撕算法篇)》(下周发布)。
一、树形结构基础
相较于链表每个节点只能唯一指向下一个节点(此处说的链表是单向链表),树则是每个节点可以有若干个子节点,因此,我们一个树形结构可以如下表示:
interface TreeNode {
data: any;
nodes: TreeNode[]
}
1.1 树的度
PS: 在图结构中,也有度的概念,分为出度和入度,如果把树看作是图的一部分的话,那么严格来说,树的度其实是出度。不过,在树形结构中,我们通常把度这个概念作为描述当前树节点有几个子节点。
即每个节点拥有几个孩子,因此,二叉树的度最大是2,链表(可以看成只有一个孩子的树)的度最大是1。
-
定理: 在一个二叉树中,度为 0 的节点比度为 2 的节点多1。
-
证明: 假如一个树有 n 个节点,那么,这棵树肯定有 n-1 条边,也就是说,点的数量=边的数量+1(这个结论针对所有树形结构都适用,不仅仅是二叉树)如下图:
这个棵树有 7 个节点,节点与节点之间的连线,也就是边只有 6 条。
那么,我们假设度为 0 的节点数量为 n0,度为 1的节点为数量 n1,度为 2 的节点数量为 n2,又因为是度为0的节点,说明他的边的数量N0=0,度为1的节点边的数量为 N1=n1 * 1,度为2的节点边的数量为N2=n2 * 2,那么总共的节点数量为:
#由上可知,边数量的表达式如下
N0=0;
N1=1*n1;
N2=2*n2;
#由上可知,节点的数量=边的数量+1
n0 + n1 + n2 = N0 + N1 + N2 + 1;
#代入N0,N1,N2得:
n0 + n1 + n2 = 0 + n1 + 2*n2 + 1;
#化简得:
n0 = n2 +1;
#即度为0的节点数量永远比度为2的节点多一个
由此,我们就证明了上面的定理,我们把这个定理换个描述或许更容易理解:
在二叉树中,只要你知道了有多少个叶子节点,那么度为2的节点数量就是叶子节点的数量减1,反之,知道度为2的节点数量,那么叶子节点的数量就是度为2的节点数量加1。
1.2 树的遍历
5
/ \
1 4
/ \
3 6
1.3 树的遍历思想
树天生就是一个适合递归遍历的数据结构,因为每一次处理左子树和右子树的时候,其实就是递归遍历的过程。
-
前序遍历:「根节点」「递归遍历左子树的输出结果」「递归遍历右子树的输出结果」
-
中序遍历:「递归遍历左子树的输出结果」「根节点」「递归遍历右子树的输出结果」
-
后序遍历:「递归遍历左子树的输出结果」「递归遍历右子树的输出结果」 「根节点」