树的一般知识
非递归遍历
preorder
最开始将根节点放进栈里。然后拿出来,按照先进后出的原则,先放右儿子,再放左儿子。对着两个点也如此操作。直到整棵树的节点被访问过。
伪代码:
void Preorder (struct node * t) {
Inistack(s);
if ( t ) Push( s, t );
while ( ! Empty( s ) {
Pop( s, t );
visit( t );
if ( t->rchild ) Push( s, t->rchild );
if ( t->lchild ) Push( s, t->lchild );
}
}
postorder
给每个节点打一个标记。节点刚进入栈里,标记是 0 0 0 。如果节点的两个儿子都已进栈,标记设置为 1 1 1 ,。标记是 0 0 0 的节点被访问时,节点的右、左儿子进栈。标记为 1 1 1 的节点被访问,节点出栈。
inorder
也是采用打标记的思路。不同的是,标记为 0 0 0 被访问,左儿子进栈,标记设置为 1 1 1 ;标记为 1 1 1 被访问,先出栈,然后右儿子进栈。
森林和树的转换
- 树转二叉树
将树用 parent-siblings 表示法表示。parent 连接最左边的孩子作为左儿子,而从左儿子依次向右连接 siblings 作为右儿子。
- 多个二叉树转一个二叉树
选定一个二叉树的根节点作为根节点,其余二叉树根节点依次作为右儿子连接。
- 二叉树转树
把 1 1 1 的步骤反过来即可。
构造Huffman树
给定了一堆字母和他们分别的出现次数,用 01 01 01 串编码。
创建一个堆(优先队列),里面的节点信息:
- 左右儿子编号
- 比较键值,在这里是出现次数
一开始编号从 1 1 1 到 n n n,全都扔堆里。每次依次拿出两个堆顶,创建一个新节点,左右儿子是这两个节点,键值是他们的和,编号顺着 + 1 +1 +1,再扔进去。直到堆里只剩下一个,就是根。
构建好 Huffman 树,从根节点向左走编码串后加 0 0 0,向右走编码串后加 1 1 1。
AVL树的节点数
如果定义空树的深度为 − 1 -1 −1, 找出深度为 i i i 的AVL树的最少节点数 f ( i ) f(i) f(i)。
f
(
0
)
=
1
f
(
1
)
=
2
f
(
2
)
=
4
…
f
(
5
)
=
20
f
(
6
)
=
33
…
f(0)=1 \\ f(1)=2 \\ f(2)=4 \\ \dots \\ f(5)=20 \\ f(6)=33 \\ \dots
f(0)=1f(1)=2f(2)=4…f(5)=20f(6)=33…
构造深度为
i
i
i 的树,应该选取根节点,然后在左子树上构造深度为
i
−
1
i-1
i−1 的树,右子树上构造深度为
i
−
2
i-2
i−2的树。这样
f
(
i
)
=
f
(
i
−
1
)
+
f
(
i
−
2
)
+
1
f(i) = f(i-1) + f(i-2) + 1
f(i)=f(i−1)+f(i−2)+1。
度与节点的关系
节点的度,是节点的子树个数,也是节点的子节点个数,还是与节点相连的次级边的个数。给出所有有度节点的度,将其相加,就得到了整棵树的边数。 + 1 +1 +1 就是节点数。
如果设树的度为 n n n,度为 i i i 的节点有 d i d_i di 个,那么可以求出叶子结点:
N = 1 + ∑ i = 1 n i × d i − ∑ i = 1 n d i = 1 + ∑ i = 1 n ( i − 1 ) × d i N = 1+\sum_{i=1}^{n} i \times d_i - \sum_{i=1}^{n} d_i = 1 + \sum_{i=1}^{n} (i-1)\times d_i N=1+i=1∑ni×di−i=1∑ndi=1+i=1∑n(i−1)×di
特别地,二叉树中,叶子结点个数等于度为 2 2 2 的节点数 + 1 +1 +1。
AVL插入和删除
在任意一棵非空平衡二叉树(AVL 树) T 1 T_1 T1中,删除某结点 v 之后形成平衡二叉树 T 2 T_2 T2,再将 v v v 插入 T 2 T_2 T2形成平衡二叉树 T 3 T_3 T3。下列关于 T 1 T_1 T1与 T 3 T_3 T3的叙述中,正确的是:(2分)
- 若 v v v 是 T 1 T_1 T1的叶结点,则 T 1 T_1 T1与 T 3 T_3 T3可能不相同
- 若 v v v 不是 T 1 T_1 T1的叶结点,则 T 1 T_1 T1与 T 3 T_3 T3一定不同
- 若 v v v 不是 T 1 T_1 T1的叶结点,则 T 1 T_1 T1与 T 3 T_3 T3一定相同
删除 2 2 2,得到
再插入 2 2 2, 就得到原来的树。