线索二叉树

来源:互联网 发布:淘宝劵 编辑:程序博客网 时间:2024/05/02 01:29

转自:http://blog.csdn.net/shunqiziranhao007/article/details/7804470


[cpp] view plaincopy
  1. /* 
  2.     数据结构C语言版 线索二叉树 
  3.     P132-135 
  4.     编译环境:Dev-C++ 4.9.9.2 
  5.     日期:2011年2月13日 
  6. */  
  7. #include <stdio.h>  
  8. #include <malloc.h>  
  9.   
  10. typedef char TElemType;  
  11.   
  12. // 二叉树的二叉线索存储表示  
  13. typedef enum{  
  14.     Link,  
  15.     Thread  
  16. }PointerTag;    // Link(0):指针,Thread(1):线索  
  17.   
  18. typedef struct BiThrNode  
  19. {  
  20.     TElemType data;  
  21.     struct BiThrNode *lchild,*rchild; // 左右孩子指针  
  22.     PointerTag LTag,RTag; // 左右标志  
  23. }BiThrNode,*BiThrTree;  
  24.   
  25. TElemType Nil = ' '// 字符型以空格符为空  
  26. BiThrTree pre; // 全局变量,始终指向刚刚访问过的结点  
  27.   
  28.   
  29. // 按先序输入二叉线索树中结点的值,构造二叉线索树T  
  30. // 空格(字符型)表示空结点  
  31. int CreateBiThrTree(BiThrTree *T)  
  32. {  
  33.     TElemType h;  
  34.     scanf("%c",&h);  
  35.     if(h==Nil)  
  36.         *T=NULL;  
  37.     else  
  38.     {  
  39.         *T=(BiThrTree)malloc(sizeof(BiThrNode));  
  40.         if(!*T)  
  41.             exit(0);  
  42.         (*T)->data=h; // 生成根结点(先序)  
  43.         CreateBiThrTree(&(*T)->lchild); // 递归构造左子树  
  44.         if((*T)->lchild) // 有左孩子  
  45.             (*T)->LTag=Link;  
  46.         CreateBiThrTree(&(*T)->rchild); // 递归构造右子树  
  47.         if((*T)->rchild) // 有右孩子  
  48.             (*T)->RTag=Link;  
  49.     }  
  50.     return 1;  
  51. }  
  52.   
  53. // 算法6.7 P135  
  54. // 中序遍历进行中序线索化。  
  55. void InThreading(BiThrTree p)  
  56. {  
  57.     if(p)  
  58.     {  
  59.         InThreading(p->lchild); // 递归左子树线索化  
  60.         if(!p->lchild) // 没有左孩子  
  61.         {  
  62.             p->LTag=Thread; // 前驱线索  
  63.             p->lchild=pre; // 左孩子指针指向前驱  
  64.         }  
  65.         if(!pre->rchild) // 前驱没有右孩子  
  66.         {  
  67.             pre->RTag=Thread; // 后继线索  
  68.             pre->rchild=p; // 前驱右孩子指针指向后继(当前结点p)  
  69.         }  
  70.         pre=p; // 保持pre指向p的前驱  
  71.         InThreading(p->rchild); // 递归右子树线索化  
  72.     }  
  73. }  
  74.   
  75. // 算法6.6 P134  
  76. // 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点。  
  77. int InOrderThreading(BiThrTree *Thrt,BiThrTree T)  
  78. {  
  79.     *Thrt=(BiThrTree)malloc(sizeof(BiThrNode)); // 建头结点  
  80.     if(!*Thrt)  
  81.         exit(0);  
  82.     (*Thrt)->LTag=Link;      //标志左孩子为指针  
  83.     (*Thrt)->RTag=Thread;    //标志右孩子为线索  
  84.     (*Thrt)->rchild=*Thrt; // 右指针回指  
  85.     if(!T) // 若二叉树空,则左指针回指  
  86.         (*Thrt)->lchild=*Thrt;  
  87.     else  
  88.     {  
  89.         (*Thrt)->lchild=T;   //头结点左指针指向树的根  
  90.         pre = *Thrt;  
  91.         InThreading(T); // 中序遍历进行中序线索化  
  92.         pre->rchild=*Thrt;  
  93.         pre->RTag=Thread; // 最后一个结点线索化  
  94.         (*Thrt)->rchild=pre;  
  95.     }  
  96.     return 1;  
  97. }  
  98.   
  99. // 算法6.5  P134  
  100. // 中序遍历二叉线索树T(头结点)的非递归算法。  
  101. int InOrderTraverse_Thr(BiThrTree T,int(*Visit)(TElemType))  
  102. {  
  103.     BiThrTree p;  
  104.     p=T->lchild; // p指向根结点  
  105.     while(p!=T)  
  106.     { // 空树或遍历结束时,p==T  
  107.         while(p->LTag==Link)  
  108.             p=p->lchild;  
  109.         if(!Visit(p->data)) // 访问其左子树为空的结点  
  110.             return 0;  
  111.         while(p->RTag==Thread&&p->rchild!=T)  
  112.         {  
  113.             p=p->rchild;  
  114.             Visit(p->data); // 访问后继结点  
  115.         }  
  116.         p=p->rchild;  
  117.     }  
  118.     return 1;  
  119. }  
  120.   
  121.   
  122. int vi(TElemType c)  
  123. {  
  124.     printf("%c ",c);  
  125.     return 1;  
  126. }  
  127.   
  128. int main()  
  129. {  
  130.     BiThrTree H,T;  
  131.     printf("请按先序输入二叉树(如:ab三个空格,表示a为根结点,"  
  132.         "b为左子树的二叉树)\n");  
  133.       
  134.     CreateBiThrTree(&T); // 按先序产生二叉树  
  135.       
  136.     InOrderThreading(&H,T); // 中序遍历,并中序线索化二叉树  
  137.       
  138.     printf("中序遍历(输出)二叉线索树:\n");  
  139.       
  140.     InOrderTraverse_Thr(H,vi); // 中序遍历(输出)二叉线索树  
  141.       
  142.     printf("\n");  
  143.       
  144.     system("pause");  
  145.     return 0;  
  146. }  
  147. /* 
  148. 输出效果: 
  149.  
  150. 请按先序输入二叉树(如:ab三个空格,表示a为根结点,b为左子树的二叉树) 
  151. ab 
  152. 中序遍历(输出)二叉线索树: 
  153. b a 
  154. 请按任意键继续. . . 
  155.  
  156. */  

原创粉丝点击