完全二叉树简介
- 完全二叉树是指,所有节点最多有两个叉
- 并且每层都得从左向右排列
- 必须上一层排满了,才能排下一层
度
是指,当前节点有几个子节点。在二叉树中,只可能有三种不同的度节点2度节点
,即有左右两个子元素的节点1度节点
,只有一个子元素的节点,由于完全二叉树的特性,1 度节点最多只有一个0度节点
,即叶子节点。叶子节点最多出现在后两层。
如下是14个节点的完全二叉树。
js
0
/ \
/ \
/ \
/ \
1 2
/ \ / \
/ \ / \
3 4 5 6
/ \ / \ / \ /
7 8 9 10 11 12 13
其实上面的完全二叉树,是可以从上往下,从左往右,放入到一个数组中,为了方便表示,上图直接把节点的值写成了数组下标。
几个公式和其证明
nodeNum = edgeNum + 1
在任何不循环的树中,其节点数量nodeNum
和边数量edgeNum
的关系是 nodeNum = edgeNum + 1
- 例如当前这棵树只有一个节点,那么
nodeNum = 1
,edgeNum = 0
- 之后,在这棵树上,每添加一个点,必须要添加一个边。例如再添加
n
个点,那么nodeNum = n + 1
,edgeNum = n
- 通过上述两个和
n
相关的关系式,可以得出nodeNum = edgeNum + 1
叶子节点推算公式 N0 = (n-1)*Nn + (n-1)*Nn-1 + ... + 2*N3 + N2 + 1
在一棵度最大为 4(这里用 n 表示,比较好,但是那个数学公式用代码表述比较麻烦,所以先用实数 4 举例)的树中,假设
- 0 度节点有
n0
个 - 1 度节点有
n1
个 - 2 度节点有
n2
个 - 3 度节点有
n3
个 - 4 度节点有
n4
个
那么总节点数nodeNum
的值为nodeNum = n0 + n1 + n2 + n3 + n4
从边的角度讲:
- 0 度节点有 0 个边
- 1 度节点有 1 个边
- 2 度节点有 2 个边
- 3 度节点有 3 个边
- 4 度节点有 4 个边
所以 edgeNum = 0*n0 + 1*n1 + 2*n2 + 3*n3 + 4*n4
又有nodeNum = edgeNum + 1
和 nodeNum = n0 + n1 + n2 + n3 + n4
可以得出 1*n1 + 2*n2 + 3*n3 + 4*n4 + 1 = n0 + n1 + n2 + n3 + n4
即叶子节点数量n0
:n0 = 3*n4 + 2*n3 + n2 + 1
这个公式适用于任何多叉树叶子节点的计算,
- 3 叉树为:
n0 = 2*n3 + n2 + 1
- 5 叉树为:
n0 = 4*n5 + 3*n4 + 2*n3 + n2 + 1
- n 叉树为:
N0 = (n-1)*Nn + (n-1)*Nn-1 + ... + 2*N3 + N2 + 1
(这里因为 md 不能用下标 n 这种表示,所以把 n 大写了。)
二叉树叶子节点公式 n0=n2+1
其中,二叉树的情况为:
节点的情况
- 0 度节点有
n0
个 - 1 度节点有
n1
个 - 2 度节点有
n2
个
边的情况:
- 0 度节点有 0 个边
- 1 度节点有 1 个边
- 2 度节点有 2 个边
按照上述推导以后得出 n0 = n2 + 1
,即叶子节点
比 2度节点
多一个
二叉树左子树位置计算公式 nl = 2n + 1
假设现在有个一个节点,它在数组中下标为n
,它和其左子树下标nl
的关系是nl = 2n + 1
,那右子树nr
就是nl + 1
即nr = 2n + 2
。证明如下。
设想这棵二叉树只绘制填充到当前元素左子树被填充的情况(可以参考成下图,5 就是此时的 n)。
js
0
/ \
/ \
/ \
/ \
1 2
/ \ / \
/ \ / \
3 4 5 6
/ \ / \ /
7 8 9 10 11
-
所有后续兄弟节点都没有子元素,即都是
叶子节点
-
所有前序兄弟都被填满,即所有前续兄弟都是
2度节点
-
叶子节点
数量n0
:n0 = 后续兄弟数量 + 前序兄弟 * 2 + 1
,+1 是因为本节点的左子节点也是叶子节点。 -
此时
nl
的位置就是当前节点位置加上所有叶子节点的数量即:nl = n + n0
(等式 1) -
2度节点
的数量为n2
: 又由于当前节点之前所有节点都被填充满了,所以当前节点之前的节点,都是2度节点
,那就是从 0 到 n-1,总共有 n 个,即n2 = n
(等式 2) -
我们从上节推算出了二叉树中
叶子节点
和2度节点
的数量关系为n0 = n2 + 1
(等式 3)
带入上述等式
js
nl = n + n0
n2 = n;
n0 = n2 + 1;
// 带入等式:
nl = n + n2 + 1
= n + n + 1
= 2n + 1
那么右子树的位置就是 2n+2
,n 的父元素的位置就是(n - 1) / 2
,对结果向下取整。
完全二叉树的层高:log2(n+1)取上界
- 在完全二叉树中,第 l 层(层数从 1 开始计算),最多存放 2^(l-1) 个节点。例如第 1 层有 1 个节点(根节点),第 2 层有 2 个节点,第 3 层有 4 个节点。
- 那么本层最后一个元素的就是第
1 + 2 + 4 + ... + 2^(l-1)
个元素,即2^l - 1
- 上一层最后一个元素就是第
2^(l-1) - 1
个。 - 那么第 n 层元素存放的就是 第
2^(l-1)
到2^l - 1
个。
例如当前有个元素,它的下标为 n,那么,它就是第n+1
个元素,假设它所处的层级是第 l 层,就有表达式:2^(l-1) <= n+1 < 2^l
(注意,2^l 即下层第一个元素),取对数得l-1 <= log2(n+1) < l
即 l 层高为:log2(n+1)
的上界(如果不是整数,就向上取整,如果是整数,就+1)。eg:
- 索引为 6 的元素,层高为
log2(6+1)的上界
,2.88,取上界为 3。 - 索引为 7 的元素,层高为
log2(7+1)的上界
,3,取上界为 4。