线索二叉树

可学习的博客:

http://blog.csdn.net/m6830098/article/details/8707814

http://book.51cto.com/art/200907/134532.htm  

http://www.lxway.com/6084102.htm                        

http://www.ihypo.net/854.html                          

https://pjf.name/post-127.html

 

实现代码:

  1 //线索二叉树,这里在二叉树的基础上添加了线索化
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 typedef char ElemType;                     
  5 typedef enum {Link,Thread} childTag;     //Link表示结点,Thread表示线索
  6 typedef struct bitNode
  7 {
  8   ElemType data;
  9   struct bitNode *lchild, *rchild;
 10   int ltag, rtag;
 11 } bitNode, *bitTree;
 12 
 13 bitTree pre;                             //创建全局变量,表示刚刚访问过的结点
 14 
 15 
 16 
 17 /*
 18 创建二叉树,其输入必须按照前序遍历的次序。
 19 T:二叉树根节点
 20 arr:按照前序遍历次序排列的各节点的值。无孩子结点时用空格代替
 21 */
 22 void create_tree(bitTree *T, char **arr)
 23 {
 24   char c;
 25   sscanf(*arr,"%c",&c);                         //读入一个结点值
 26   (*arr)++;
 27   if(' '== c)                                     //如果是空格,表示空结点
 28     {
 29       *T=NULL;
 30     }
 31   else 
 32     {
 33       *T=(bitTree)malloc(sizeof(bitNode));         //构造新结点
 34       (*T)->data=c;
 35       (*T)->ltag=Link;
 36       (*T)->rtag=Link;
 37       create_tree(&(*T)->lchild,arr);            //构造新结点的左孩子
 38       create_tree(&(*T)->rchild,arr);            //构造新结点的右孩子
 39     }
 40 }
 41 
 42 
 43 /*
 44 访问结点信息
 45 */
 46 void visit(bitTree T)
 47 {
 48     printf("| %d | %c | %d |\n",T->ltag,T->data,T->rtag);
 49 }
 50 
 51 
 52 /*
 53 前序遍历访问二叉树
 54 */
 55 void pre_order_traverse(bitTree T,int level)
 56 {
 57   if(T)
 58     {
 59       visit(T);
 60       pre_order_traverse(T->lchild,level+1);
 61       pre_order_traverse(T->rchild,level+1);
 62     }
 63 }
 64 
 65 /*
 66 中序遍历二叉树,对其进行线索化
 67 */
 68 void in_order_threading(bitTree T)
 69 {
 70   if(T)
 71     {
 72       in_order_threading(T->lchild);             //左孩子线索化
 73       if(!T->lchild)                             //如果左孩子为空,则将其指向直接前驱
 74     {
 75       T->lchild=pre;
 76       T->ltag=Thread;
 77     }
 78       if(!pre->rchild)                             //如果上一个结点的右孩子为空,则将其指向直接后继。(注意:只有访问到下一个结点时,才会知道本结点的后继是谁)
 79     {
 80       pre->rchild=T;
 81       pre->rtag=Thread;
 82     }
 83       pre=T;
 84       in_order_threading(T->rchild);             //右孩子线索化
 85     }
 86 }
 87 
 88 /*
 89 加入一个头结点,使二叉线索树成一个封闭环
 90 P:带有头结点的二叉树。头结点的左孩子指向二叉树T;右孩子指向T树中的最后一个叶子结点
 91 T:不带有头结点的二叉树。
 92 */
 93 void in_thread(bitTree *P,bitTree T)
 94 {
 95   (*P)=(bitTree)malloc(sizeof(bitNode));         //构造新加入的头结点
 96   (*P)->ltag=Link;
 97   (*P)->rtag=Thread;
 98   (*P)->rchild=*P;
 99   if(!T)                                         //如果二叉树为空,则P的孩子指向自己。
100     {
101       (*P)->lchild=*P;
102     }
103   else
104     {
105       (*P)->lchild=T;
106       pre=*P;
107       in_order_threading(T);                     //对二叉树进行线索化
108       (*P)->rchild=pre;                         //将头结点右孩子指向最后一个叶子结点
109       pre->rtag=Thread;                         //将最后一个叶子结点的右孩子指向头结点。这样,环就形成了。
110       pre->rchild=*P;
111     }
112 }
113 
114 /*
115 非递归方式:中序遍历二叉树(树必须带有头结点,且已经线索化)
116 P:带有头结点的二叉树
117 */
118 void in_order_traverse(bitTree P)
119 {
120   bitTree T;
121   T=P->lchild;
122   while(T!=P)                                     //判断是否空树
123     {
124       while(T->ltag==Link)                         //从左孩子开始,直到叶子结点
125         {
126           T=T->lchild;
127         }
128       visit(T);
129       while(T->rtag==Thread && T->rchild!=P) //根据线索,访问后继结点。并且后继结点不是指向头结点的
130         {
131           T=T->rchild;
132           visit(T);
133         }
134       T=T->rchild;
135     }
136 }
137 
138 
139 int main()
140 {
141   bitTree P,T;
142   int level =1;                     //表示该结点的深度
143   char *arr="ab d  ce   ";             //构造二叉树所需结点(按前序遍历方式输入)
144   create_tree(&T,&arr);             //构造二叉树
145   printf("pre_order_traverse:先序遍历:\n");
146   pre_order_traverse(T,level);         //前序遍历输出二叉树
147   printf("in_order_traverse:中序遍历:\n");
148   in_thread(&P,T);                     //二叉树线索化
149   in_order_traverse(P);             //输出线索化后的二叉树
150   return 0;
151 }

 

posted @ 2015-09-29 16:15  Vmetrio  阅读(218)  评论(0编辑  收藏  举报