中序线索化的线索二叉树的前序遍历、中序遍历和后序遍历

前序遍历的后继结点:

(1)P的左子树不为空,此时P的后继结点就是P的左儿子;

(2)P的左子树为空但右子树不为空,此时P的后继结点就是P的右儿子;

(3)P的左右子树均为空,此时在从P开始的右线索序列中,第一个有右儿子的节点的右儿子或者头结点就是P的后继结点。


 

中序遍历的后继结点:

若一个节点的右子树为空,此时右线索所指节点即为所求;若这个节点的右子

树不为空,此时它的后继结点是其右子树的最左节点。


 

 后序遍历的后继结点:

当一个节点是它的双亲节点的右孩子时,它的后序遍历的后继就是双亲节点。当它是双亲节点的左孩子,且双亲节点没有右子树时,它的后序遍历的后继也是双亲节点。当它是双亲节点的左孩子,且双亲节点有右子树时,它的后序遍历的后继是双亲节点右子树中的最左节点。


脑子已被搅乱,为了节省代码量和简化过程,后序遍历采用了递归的方法,请见谅。

 
  
  1. #include<stdio.h>  
  2. //输入样例:1 2 3 0 0 4 0 5 0 0 6 0 0  
  3. typedef enum {Link, Thread} PointerTag;//指针标志  
  4. typedef int DataType;  
  5. typedef struct BiThreTree              //定义节点  
  6. {  
  7.     PointerTag LTag, RTag;  
  8.     DataType data;  
  9.     struct BiThreTree *lchild, *rchild;  
  10. }BiThreTree;  
  11.  
  12. BiThreTree *pre;                       //全局变量,用于二叉树的线索化  
  13. BiThreTree *CreateTree()               //按先序输入建立二叉树  
  14. {  
  15.     BiThreTree *T;  
  16.     DataType e;  
  17.     scanf("%d", &e);  
  18.     if(e==0)  
  19.         T=NULL;  
  20.     else 
  21.     {  
  22.         T=new BiThreTree;  
  23.         T->data=e;  
  24.         T->LTag=Link;        //初始化时指针标志均为Link  
  25.         T->RTag=Link;  
  26.         T->lchild=CreateTree();  
  27.         T->rchild=CreateTree();  
  28.     }  
  29.     return T;  
  30. }//  
  31.  
  32.  
  33. void InThread(BiThreTree *T)//对二叉树进行中序线索化的算法  
  34. {  
  35.     BiThreTree *p;  
  36.     p=T;  
  37.     if(p)  
  38.     {  
  39.         InThread(p->lchild);//左子树线索化  
  40.         if(!p->lchild)//if左子树为空  
  41.         {  
  42.             p->LTag=Thread;  
  43.             p->lchild=pre;  
  44.         }  
  45.         if(!pre->rchild)//if右子树为空  
  46.         {  
  47.             pre->RTag=Thread;  
  48.             pre->rchild=p;  
  49.         }  
  50.         pre=p;//前驱指向当前节点  
  51.         InThread(p->rchild);//右子树线索化  
  52.     }  
  53. }//  
  54.  
  55.  
  56.  
  57. BiThreTree *InOrderThrTree(BiThreTree *T)//中序线索化二叉树  
  58. {  
  59.     BiThreTree *Thre;      //Thre为头结点的指针  
  60.     Thre=new BiThreTree;  
  61.     Thre->lchild=T;  
  62.     Thre->rchild=Thre;  
  63.     pre=Thre;  
  64.     InThread(T);  
  65.     pre->RTag=Thread;  
  66.     pre->rchild=Thre;  
  67.     Thre->rchild=pre;  
  68.     return Thre;  
  69. }//  
  70.  
  71.  
  72.  
  73. void InThrTravel(BiThreTree *Thre)//中序遍历二叉树  
  74. {  
  75.     BiThreTree *p;  
  76.     p=Thre->lchild;//Thre是树的"头"  
  77.     while(p!=Thre)//指针回指向头结点时结束  
  78.     {  
  79.         while(p->LTag==Link)//Link表示子树存在  
  80.             p=p->lchild;  
  81.         printf("%4d", p->data);  
  82.         while(p->RTag==Thread&&p->rchild!=Thre)//Thread表示右子树不存在,存在的"右子树"是线索  
  83.         {  
  84.             p=p->rchild;  
  85.             printf("%4d", p->data);  
  86.         }  
  87.         p=p->rchild;  
  88.     }  
  89. }//  
  90.  
  91.  
  92. void FirstThrTravel(BiThreTree *Thre)//先序遍历线索二叉树  
  93. {  
  94.     BiThreTree *p;  
  95.     p=Thre->lchild;  
  96.     while(p!=Thre)  
  97.     {  
  98.         printf("%4d", p->data);  
  99.         while(p->LTag==Link)  
  100.         {  
  101.             p=p->lchild;  
  102.             printf("%4d", p->data);  
  103.         }  
  104.         if(p->RTag==Thread)  
  105.             {p=p->rchild;}  
  106.         if(p->RTag==Link)  
  107.             {p=p->rchild;}  
  108.     }  
  109. }//  
  110.  
  111.  
  112.  
  113.  
  114. void LastThrTravel(BiThreTree *p)//递归实现后序遍历线索二叉树  
  115. {  
  116.     if(p!=NULL)  
  117.     {  
  118.         if(p->LTag==Link)  
  119.             LastThrTravel(p->lchild);  
  120.         if(p->RTag==Link)  
  121.             LastThrTravel(p->rchild);  
  122.         printf("%4d", p->data);  
  123.     }  
  124.  
  125. }  
  126.  
  127. int main()  
  128. {  
  129.     BiThreTree *T, *Thre;  
  130.     printf("请按前序遍历输入线索二叉树的元素,用0代表空儿子:\n");  
  131.     //1 2 3 0 0 4 0 5 0 0 6 0 0  
  132.     T=CreateTree();  
  133.     Thre=InOrderThrTree(T);  
  134.  
  135.     printf("\n中序遍历该线索二叉树的结果为:\n");  
  136.     InThrTravel(Thre);  
  137.  
  138.     printf("\n先序遍历该线索二叉树的结果为:\n");  
  139.     FirstThrTravel(Thre);  
  140.  
  141.     printf("\n后序遍历该线索二叉树的结果为:\n");  
  142.     LastThrTravel(Thre->lchild);  
  143.  
  144.     getchar();  
  145.     return 0;  
  146. }