二叉树
定义:二叉树是一种树型结构,它的特点是每个结点至多只有两棵子树,并且,二叉树的子树有左右之分,次序不能任意颠倒
  性质:
   ①在二叉树的第i层上至多有2^(i-1 )个结点(i≥1)
   ②深度为k的二叉树至多有2^k-1个结点
   ③对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n0=n2+1
   ④具有n个结点的完全二叉树的深度为floor(log2 n)+1
  二叉树的存储结构
   1.顺序存储结构
   
| 1 | 
 | 
将完全二叉树上的编号为i的结点元素存储在如上定义的一位数组中下标为i-1的分量中。
最坏的情况下,一个深度为k且只有k个结点的单支树(树中不存在度为2的结点)却需要长度为2^k-1的一位数组
仅适合用于完全二叉树
   2.链式存储结构
   
| 1 | typedef struct BiTNode{ | 
遍历二叉树
1.先序遍历
| 1 | Status Bitree::PreOrderTraverse(const BiTree &T) { | 
| 1 | Status PreOrderStack(const BiTree T){ | 
2.中序遍历
| 1 | Status Bitree::InOrderTraverse(const BiTree &T) { | 
| 1 | Status InOrderStack(const BiTree &T) { | 
3.后序遍历
| 1 | Status Bitree::PostOrderTraverse(const BiTree &T) { | 
| 1 | Status PostOrderStack(BiTree T){ | 
4.层序遍历
| 1 | Status Bitree::LevelOrderTraverse(const BiTree &T) { | 
线索二叉树
利用n个结点的二叉树必有n+1个空链域存放指向某种遍历次序下的前驱结点或后继结点的指针
    图示
     
     
    数据结构
    
| 1 | typedef enum PointTag{Link,Thread}; //Link==0;指针,Thread==1;线索 | 
树和森林
  相关术语
   树的结点:包含一个数据元素及若干指向其子树的分支
   度:结点拥有的子树数称为结点的度(Degree)
   叶子:度为0的结点
   分支结点:度不为0的结点
  结点的层次
   从根开始定义起,根为第一层,根的孩子为第二层
   深度(Depth):树中结点的最大层次
   有序树:结点各子树看成从左至右是有次序的(即不能交换的)
   *无序树:结点各子树看成从左至右是无次序的(即可以交换的)
   *森林(Forest):m(m≥0)棵互不相交的树的集合
  存储结构
   1.双亲表存储表示
   
| 1 | 
 | 
利用每个结点(除根节点外)只有唯一双亲的性质求结点的孩子时需要遍历整个结构
   2.孩子链表存储表示
   
| 1 | typedef struct CTNode{ | 
便于一些涉及孩子的操作,不适用于找双亲
   3.二叉链表(孩子-兄弟)存储表示):
   
| 1 | typedef structCSNode{ | 
便于实现各种树的操作
森林与二叉树的转换
   1.树变二叉树
    兄弟相连,保留长子的连线
   2.二叉树变树
    结点的右孩子与其双亲连
   3.森林变二叉树
    树变而二叉树,各个树的根相连
哈夫曼树
   路径长度
    路径上的分支数目
   树的路径长度
    从树根到每个结点的路径长度之和
   树的带权路径长度
    所有叶子结点的带权路径长度之和
    WPL=∑(k=1,n)wk*lk
   WPL最小的二叉树称作最优二叉树或哈夫曼树
   构造
    权值越大,应分配的路径长度越小
    故:
     将所有带权结点加入集合,每次从结合中选取权值最小的两个结点,生成一个权值为两者权值之和的父节点,父节点加入集合,两个子节点移出集合,重复操作,直至集合只剩下一个结点,即根结点。
   应用
    前缀编码
   数据结构
   
| 1 | typedef struct{ | 
二叉树代码
| 1 | 
 | 
哈夫曼树代码
| 1 | 
 | 

 
 