1.二叉树的一些性质:
对于一棵非空二叉树,如果其叶节点数为n0,度为2的非叶节点数为n2,则n0=n2+1。 证明可以从边数的不同表示方法着手。
具有N个结点的完全二叉树的深度为log2(n+1)取上整。
2.满二叉树和完全二叉树
满二叉树的每一层节点都到达了最大个数,完全二叉树是从第一层到K-1层都是满的,最下面第K层或是满的,或是从右向左连续缺若干结点。
3.二叉树的存储表示
如果在数据处理过程中二叉树的大小和形态不发生剧烈的动态变化 ,适宜采用数组方式。对于完全二叉树来说,这种方式最简单最省存储,对于普通二叉树来说可能会造成很大的浪费。
对于形态剧烈变化的二叉树,可以采用链表存储。二叉链表是:存放data,左右子女结点指针。三叉链表还多了一个指向父结点的指针。二叉链表和三叉链表可以是静态指针结构,即把链表存放在一个一维数组中,数组中的每一个数组元素是一个结点,包括data,parent,leftchild,rightchild。
4.用广义表表示二叉树
如: A(B(D,E(G,)),C(,F))#
*把如上所示的输入变成二叉树的算法。
5.二叉树的遍历算法
1)递归 前序、中序、后序 简单
后序遍历可以用来求树高;前序遍历可以用来实现复制构造函数,也可以用来判断两棵二叉树是否相等。
2)非递归
前序遍历:需要使用栈。 先把根节点push,while(栈不为空){pop,再 visit,把右子女结点push进栈,再把左子女结点push进栈 }
层遍历: 需要使用队列。 方法跟上面的差不多。
中序遍历:需要使用栈。 算法是:(大概写写)
stack s;
BinTreeNode p=root;
do{
while(p!=null){
s.push(p);
p=p.left;
}
if(!s.empty()){
s.pop(p);
visit(p);
p=p.right;
}
}while(p!=null || !s.empty());
后序遍历: 也要用到栈,但是要加一个flag记录是第一次访问到还是第二次访问到(即刚才是在左子树还是右子树)。
6.线索二叉树
利用空的leftChild域存放前驱结点指针,利用空的rightChild域存放后继结点指针。
7.树的存储表示
1)广义表 如R(A(D,E),B,C(F,G,H) )
2) 父指针表示法 一个数组,存放data和parentIndex
3)子女链表表示法 一个数组,存放data和一条子女结点链表
4)长子-兄弟链表表示法 结点数据结构为 data,firstchild,nextSibling(下一个兄弟)
8.树的深度优先遍历和广度优先遍历
深度优先:通常有两种,即前序,后序
广度优先:用个队列
9.Huffman树
如图
*不唯一!
应用:
最优判定树,Huffman编码