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 的步骤反过来即可。
给定了一堆字母和他们分别的出现次数,用 01 01 01 串编码。
创建一个堆(优先队列),里面的节点信息:
一开始编号从 1 1 1 到 n n n,全都扔堆里。每次依次拿出两个堆顶,创建一个新节点,左右儿子是这两个节点,键值是他们的和,编号顺着 + 1 +1 +1,再扔进去。直到堆里只剩下一个,就是根。
构建好 Huffman 树,从根节点向左走编码串后加 0 0 0,向右走编码串后加 1 1 1。
如果定义空树的深度为 − 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 树) 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分)
删除 2 2 2,得到
再插入 2 2 2, 就得到原来的树。