typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
    ElementType Data; /* 结点数据 */
    BinTree Left;     /* 指向左子树 */
    BinTree Right;    /* 指向右子树 */
};


//中序遍历
void InorderTraversal( BinTree BT )
{
    if( BT ) {
        InorderTraversal( BT->Left );
        /* 此处假设对BT结点的访问就是打印数据 */
        printf("%d ", BT->Data); /* 假设数据为整型 */
        InorderTraversal( BT->Right );
    }
}
//先序遍历
void PreorderTraversal( BinTree BT )
{
    if( BT ) {
        printf("%d ", BT->Data );
        PreorderTraversal( BT->Left );
        PreorderTraversal( BT->Right );
    }
}
//后序遍历
void PostorderTraversal( BinTree BT )
{
    if( BT ) {
        PostorderTraversal( BT->Left );
        PostorderTraversal( BT->Right );
        printf("%d ", BT->Data);
    }
}
//按层遍历
void LevelorderTraversal ( BinTree BT )
{ 
    Queue Q; 
    BinTree T;
    if ( !BT ) return; /* 若是空树则直接返回 */
    
    Q = CreatQueue(); /* 创建空队列Q */
    AddQ( Q, BT );
    while ( !IsEmpty(Q) ) {
        T = DeleteQ( Q );
        printf("%d ", T->Data); /* 访问取出队列的结点 */
        if ( T->Left )   AddQ( Q, T->Left );
        if ( T->Right )  AddQ( Q, T->Right );
    }
}
要已知两种遍历结果,还原一棵二叉树:前序/后序/按层+中序遍历。
也就是说,中序遍历是必要的。
本部分内容在我的另一篇博客有详细解释:https://www.cnblogs.com/fighterkaka22/p/14203479.html
观察前面遍历二叉树的举例,可以发现,该三个序列分别为波兰式、正常表达式和逆波兰式。
当我们希望得到二叉树中某一个结点的前驱或者后继结点时,普通的二叉树是无法直接得到的,只能通过遍历一次二叉树得到。每当涉及到求解前驱或者后继就需要将二叉树遍历一次,非常不方便。因此考虑,是否能够改变原有的结构,将结点的前驱和后继的信息存储进来。
记ptr指向二叉链表中的一个结点,以下是建立线索的规则:
(1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;
(2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;
显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。

中序遍历进行二叉树线索化代码:
void InThreading(BiThrTree B,BiThrTree *pre) {
  if(!B) return;
 
  InThreading(B->lchild,pre);   
//--------------------中间为修改空指针代码---------------------
 
  if(!B->lchild){                   //没有左孩子 
    B->LTag = Thread;               //修改标志域为前驱线索
    B->lchild = *pre;               //左孩子指向前驱结点
  }
 
  if(!(*pre)->rchild){              //没有右孩子
    (*pre)->RTag = Thread;          //修改标志域为后继线索
    (*pre)->rchild = B;             //前驱右孩子指向当前结点
  }
 
  *pre = B;                         //保持pre指向p的前驱
//---------------------------------------------------------
  InThreading(B->rchild,pre);
}
//非递归遍历线索二叉树
Status InOrderTraverse(BiThrTree T) {
  BiThrNode *p = T->lchild;
  while(p!=T){
    while(p->LTag==Link) p = p->lchild;    //走向左子树的尽头
    printf("%c",p->data );
    while(p->RTag==Thread && p->rchild!=T) {  //访问该结点的后续结点
      p = p->rchild; 
      printf("%c",p->data );
    }
    p = p->rchild;
  }
  return OK;
}





前缀编码:任意一个字符的编码都不是另一个字符的编码的前缀。
举例:如果需传送的电文为 ‘ABACCDA‘:

编码: A:0, C:10,B:110,D:111
任意一个叶子结点都不可能在其它叶子结点的路径中。
实际上,所有的树都可以通过孩子兄弟表示法表示为二叉树。
原文:https://www.cnblogs.com/fighterkaka22/p/14209510.html