结点的度:结点拥有的子树数
树的度:树内各结点度的最大值
叶子:度为0的结点
非终端结点:度不为0的结点
双亲和孩子:结点的子树的根为该结点的孩子,该结点为孩子的双亲
兄弟:同一个双亲的孩子之间互称为兄弟
树的深度:树中结点的最大层次
二叉树:子树有左右之分,次序不能颠倒
满二叉树:深度为k且有-1个结点的二叉树
完全二叉树:叶子结点只可能在层次最大的两层上出现
树的结点数:n
树的分支数B=n-1 (B所有结点度之和)
二叉树的性质:
(1)在二叉树的第i层上最多有(i>=1)个结点
(2)深度为k的二叉树最多有-1个结点
(3)任何一棵二叉树=+1 度为0的结点=度为2的结点+1
(4)具有n个结点的完全二叉树深度+1
(5)编号 i=1:二叉树的根
2*i>n:i无左孩子
2*i+1>n:无右孩子
二叉树存储:顺序存储(按层次存储,从左到有 包括空的结点)、链式存储
二叉树的遍历:先序遍历、中序遍历、后序遍历
typedef struct BiTNode{
int data;
BiTNode *rchild,*lchild;
}BiTNode,*BiTree;
//中序遍历二叉树T的递归算法
void InOrderTraverse(BiTree T) {
if(T) {
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild)
}
}
按照先序遍历的序列创建二叉链表:
void CreateBiTree(BiTree &T) {
//按线序次序输入二叉树中结点的值,创建二叉链表表示的二叉树T
cin>>ch;
if(ch=='#') T=NULL;
else{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
线索:指向结点前驱和后继的指针
线索二叉树:加上线索的树,保存在动态过程中得到的有关前驱和后继的信息
LTag=1 lchild域指示的结点前驱
0 lchild域指示的结点的左孩子
RTag=1 rchild域指示的结点后继
0 rchild域指示的结点的右孩子
树和森林
1、树的存储结构:
1)双亲表示法:以一组连续的存储单元存储树的结点,每个结点除了数据域data外,还设一个parent域用于指示其双亲结点的位置
2)孩子表示法:可用多重链表,每个结点有多个指针域,每个指针指向一颗子树的根节点
3)孩子兄弟表示法:又称二叉树表示法、二叉链表表示法(结点两个指针域一个数据域)
结点两个指针域:一个指向第一个孩子 另一个指向下一个兄弟(左孩子右兄弟)
2、森林和二叉树的转换
1)森林转二叉树 左孩子右兄弟
2)二叉树转森林
n个结点K个边的森林有n-k棵树
3、遍历
先根次序遍历:和二叉树的先序遍历相同
后根次序遍历:和二叉树的中序遍历相同
哈夫曼树
哈夫曼树:最优树,带权路径最短
权值大的离n较近
树的带权路径长度WPL所有叶子结点带权路径之和
构造哈夫曼树(n个):
产生n-1个新的结点 n0=n n2=n-1
没有度为1的结点
结点总个数:2n-1
哈夫曼编码
前缀编码:任何一个编码都不是其他任何编码的前缀
哈夫曼编码是前缀编码:左0右1
练习:
1、Given a tree of degree 5. Suppose that the numbers of nodes of degrees 1, 2, 3, 4, 5 are 3, 1, 2, 4, 3, respectively.
Then the number of leaf nodes must be _. 30
解析:设度为0的结点有x个,n=B+1
3+1+2+4+3+x=1*3+2*1+3*2+4*4+5*3+1
x=30
2、对于任意一棵高度为 5 且有 10 个结点的二叉树,若采用顺序存储结构保存,每个结点占 1 个存储单元(仅存放结点的数据信息),则存放该二叉树需要的存储单元的数量至少是:
31(要按最大值开辟空间)
3、由3 个结点可以构造出多少种不同的二叉树( ) 5
4、Given a tree of degree 3. Suppose that there are 4 nodes of degree 2 and 3 nodes of degree 3. Then the number of leaf nodes must be ____. 11
5、具有五层结点的完全二叉树至少有()个结点。 16
6、已知一棵普通树的广义表表示为a(b, c(e(h, i, j), f), d(g)),则此树的度为()。3
7、一棵完全二叉树上有1001个结点,其中叶子结点的个数是( )个。
=+1,完全二叉树 度为1的结点只能为1个或0个
1001=++1+0或1 =500
叶子节点501
8、一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶子结点个数是 。 82
9、一棵高度为h的并且只有h个结点的二叉树,采用顺序存储结构存放在R[1..n]中,则n应该至少是( )。 -1
10、在一棵具有n个结点的二叉树中,所有结点的空子树个数等于( )
n+1(假设有三个结点 画个图)
11、含n个结点的3次树的最小高度是( ),最大高度是( )。
公式:
m=3
log3(2n+1),n-2
12、若完全二叉树中结点个数为50,则叶子数必为 25
n0+n1+n2=50 n0=n2+1
2*n2+1+n1=50 2*n2+n1=49 n1=1 n2=24 n0=25
13、一棵二叉树的先序序列:abdfcegh,中序序列:bfdagehc。该二叉树中右子树的根结点是()。 c
14、一棵有n个结点的二叉树,按层次从上到下,同一层从左到右顺序存储在一维数组A[1..n]中,则二叉树中第i个结点(i从1开始用上述方法编号)的右孩子在数组A中的位置是( )
条件不充分,无法确定
15、若X是后序线索二叉树中的叶结点,且X存在左兄弟结点Y,则X的右线索指向的是( )。
X的父结点
16、建立与遍历二叉树
以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’, 表示该二叉树是空树,否则该字符是相应结点的数据元素。读入相应先序序列,建立二叉链式存储结构的二叉树,然后中序遍历该二叉树并输出结点数据。
输入格式:
字符串形式的先序序列(即结点的数据类型为单个字符)
输出格式:
中序遍历结果
输入样例:
在这里给出一组输入。例如:
ABC##DE#G##F###
输出样例:
在这里给出相应的输出。例如:
CBEGDFA
#include<iostream>
using namespace std;
typedef struct BiTNode{
char data;
BiTNode *rchild,*lchild;
}BiTNode,*BiTree;
//二叉链式存储结构的二叉树
void CreatTree(BiTree &T){
char c;
cin>>c;
if(c=='#') T=NULL;
else{
T=new BiTNode;
T->data=c;
CreatTree(T->lchild);
CreatTree(T->rchild);
}
}
//中序遍历该二叉树
void InOrderTraverse(BiTree T){
if(T){
InOrderTraverse(T->lchild) ;
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
main(){
BiTree T;
CreatTree(T);
InOrderTraverse(T);
}
17、二叉树中序线索化后,存在空指针域。
18、对N(≥2)个权值均不相同的字符构造哈夫曼树,则树中任一非叶结点的权值一定不小于下一层任一结点的权值。
19、在中序线索二叉树中,每一非空的线索均指向其祖先结点。
20、设一段文本中包含4个对象{a,b,c,d},其出现次数相应为{4,2,5,1},则该段文本的哈夫曼编码比采用等长方式的编码节省了多少位数? 2
长方式的编码2*(4+2+5+1)
哈夫曼:4*2+2*3+5*1+1*3
21、How many trees are in the forest with N nodes and K edges? N−K
22、设森林T中有4棵树,第一、二、三、四棵树的结点个数分别是n1,n2,n3,n4,那么当把森林T转换成一棵二叉树后,根结点的右子树上有( )个结点。 n2+n3+n4
23、某二叉树结点的中序序列为BDAECF,后序序列为DBEFCA,则该二叉树对应的森林包括( )棵树。 3
24、讨论树、森林和二叉树的关系,目的是为了( )。
借助二叉树上的运算方法去实现对树的一些运算
25、设F是一个森林,B是由F变换得的二叉树。若F中有n个非终端结点,则B中右指针域为空的结点有( )个。 n+1