树与二叉树
术语:
叶子结点:度为0的结点
树的度:
二叉树
定义:
特点:
- 每个结点的度<=;
- 是有序树
二叉树的性质:
- 若二叉树的层次从1开始,则在二叉树的第i层最多有个结点
- 深度为k的二叉树最多有-1个结点(k>=1)
- 对任何一颗二叉树,如果其叶子结点个数为n0,度为2的叶子结点个数为n2,则有n0=n2+1
- 具有n个结点的完全二叉树的深度为{log2N}+1
- 如果将一颗有n个结点的完全二叉树的结点按层序连续编号1,2...n,然后按此结点编号将树中各结点顺序地存放于一个一维数组中,并简称编号为i的结点为结点i。则有以下关系:
- 若i==1,则i是二叉树的根,无双亲
- 若i>1,则i的双亲为【i/2】
- 若2*i<=n,则i的左孩子为2*i,否则则无左孩子
- 若2*i+1<=n,则i的右孩子为2*i+1,否则无右孩子
- 若i为偶数,且i!=n,则其右兄弟为i+1
- 若i为奇数,且i!=1,则其左兄弟为i-1
- i所在层次为{log2i}+1
存储:
顺序存储
连式存储
二叉链表的定义:
typedef struct BiTnode
{
TElemType data;
Struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
三叉链表的定义:
二叉树的遍历:按照某种次序访问树中的结点,并且每个结点仅且访问一次。
遍历的结果:产生一个关于结点的线性序列
设访问根节点记作D,右子树记作R,左子树记作L,则可能的顺序有:
先序 | 中序 | 后序 | 逆先序 | 逆中序 | 逆后序 |
DLR | LDR | LRD | DRL | RDL | RLD |
线索二叉树
线索:指向结点前驱和后继的指针
若结点有左孩子,则lchild指示其左孩子,否则lchild存储指向该结点前驱结点的指针
若结点有右孩子,则rchild指示其右孩子,否则rchild存储指向该结点后继结点的指针
实质:对一个非线性结构进行线性化操作,使每个结点
哈夫曼树及其应用
路径长度:连接两结点的路径上的分支数
树的路径长度:各结点根结点的路径长度之和
哈夫曼树:带权路径长度达到最小的二叉树即为哈夫曼树(最优二叉树)
在哈夫曼树中,权值大的结点离根最近。
- 哈夫曼树的构造:假设有n个权值,则构造出的哈夫曼树有n个叶子节点,n个权值分别设为w1,w2...wn,则哈夫曼树构造规则是:
- 将w1,w2...wn看成是有n棵树的森林(每棵树仅有一个结点)
- 在森林中选出两个根节点的权值最小的树合并,作为一颗新树的左右子树,且新树的根节点权值为其左右子树根节点的权值之和。
- 从森林中删除选取的两棵树,并将新树加入森林
- 重复2,3步,直到森林中只剩下一棵树,这棵树就是我们所求的哈夫曼树
哈夫曼编码
主要用途是实现数据压缩,左分支赋0,右分支赋1,得哈夫曼编码(变长编码)
总编码长度正好等于哈夫曼树的带权路径长度WPL
哈夫曼编码是一种无前缀的编码,解码时不会混淆。
树和森林及其与二叉树之间的转换
树的存储方法:
双亲表示法:以一组连续的存储单元来存放树中的结点,每个结点有两个域,一个是data域,存放结点信息,另一个是parent域,用来存放双亲的位置(指针)。
孩子表示法:将一个结点所有孩子链接成一个单链表型,而树中有若干个结点,固有若干个单链表,每个单链表有一个表头结点,所以表头结点用一个数组来描述。
双亲孩子表示法:将上述两种方法结合起来。
孩子兄弟表示法:类似于二叉链表,但第一根链指向第一个孩子,第二根链指向下一个兄弟。
数转换成二叉树:
- 相邻兄弟之间连线
- 抹掉双亲与除左孩子之外其他孩子之间的连线
- 将树作适当的旋转
森林转成二叉树:
- 将森林中每一棵树分别转成二叉树
- 使第n棵树接入到第n-1棵的右边并成为它的右子树,第n-1棵树接入到第n-2棵的右边并成为它的右子树...,第2棵二叉树接入到第1棵树的右边并成为它的右子树,直到最后剩下一棵二叉树为止。
二叉树还原成树或者森林:
- 将二叉树的根结点的右链及右链的右链全部断开,得到若干棵无右子树的二叉树
- 将1中得到的每一棵二叉树都还原成树(与树转换成二叉树的步骤刚好相反)
树和森林的遍历
在树和森林中,一个结点可能有两棵以上的子树,所以不宜讨论它们的中序遍历,即树和森林只有先序和后序遍历。
先序遍历:
树的先序遍历:若树非空,则先访问根节点,然后依次先序遍历各子树
森林的先序遍历:若森林非空,则先访问森林中第一棵树的根节点,再先序遍历第一棵树的各子树,接着先序遍历第二棵树、第三棵树、....、知道最后一棵
后序遍历:
树的后序遍历:若树非空,则依次后序遍历各子树,最后访问根节点。
森林的后序遍历:按顺序后序遍历森林中的每一棵树。
另外,请注意,树和森林的先序遍历等价于它转换成的二叉树的先序遍历,树和森林的后序遍历等价于它转换成二叉树的中序遍历。