二叉树后序遍历的非递归算法(C语言)

首先非常感谢‘hicjiajia’的博文:二叉树后序遍历(非递归)

这篇随笔开启我的博客进程,成为万千程序员中的一员,坚持走到更远!

折磨了我一下午的后序遍历中午得到解决,关键在于标记右子树是否被访问过,考虑过修改二叉树结点的数据结构,增加一个visit域,或者建一个栈存储已访问的结点。都比较麻烦没有调试成功。若将右子树也入栈,如果没有访问标记的话,会改变访问的次序,甚至出现死循环,这是比较危险的情况。从借鉴的博文里,摘录并改写为C的代码,基本上没有改动。后续问题努力写出自己的原创代码。

二叉树存储的数据类型为int型,用数字0表示子树为空

输入:1 2 3 0 8 0 0 4 0 0 5 6 0 0 7 0 0

得到后序遍历结果:83426751

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #define OK              1
 5 #define ERROR           0
 6 #define MaxSize         100 
 7 
 8 typedef int ElemType;
 9 typedef int Status;
10 
11 typedef struct BTNode{
12     ElemType    data; 
13     struct BTNode *lchild,*rchild; 
14 }BTree;
15 
16 typedef struct St{
17     struct BTNode*    data[MaxSize];
18     int               top;
19 }Stack; 
20 //1.按先序次序生成二叉树
21 BTree* CreateT(){
22     BTree *BT;
23     ElemType ch;
24     scanf("%d",&ch);
25     if(ch==0)
26         BT=NULL;
27     else{
28         BT=(BTree*)malloc(sizeof(BTree));
29         if(!BT){exit(OVERFLOW);}        
30         BT->data=ch;
31         BT->lchild=CreateT();
32         BT->rchild=CreateT();
33     }
34     return BT;
35 } 
36 
37 //4.后序遍历
38 Status PostOrder(BTree *BT) {
39     if(BT){
40         PostOrder(BT->lchild);
41         PostOrder(BT->rchild);
42         printf("%3d",BT->data);
43         return OK;
44     }
45     else return ERROR;
46 }
47 //4.后序遍历-非递归 
48 Status PostOrder2(BTree *BT) {
49     Stack s,s2;
50     BTree *T;
51     int flag[MaxSize]; 
52     s.top=0;
53     T=BT;
54     while(s.top!=0||T){
55         while(T)
56         {
57             s.data[s.top++]=T;
58             flag[s.top-1]=0;
59             T=T->lchild;
60          } 
61          while(s.top!=0&&flag[s.top-1]==1){
62              T=s.data[--s.top];
63              printf("%3d",T->data);
64          }
65          if(s.top!=0){
66              flag[s.top-1]=1;
67              T=s.data[s.top-1];
68              T=T->rchild;
69          }
70          else   break;
71     }
72     return OK;
73 }
74 int main(){
75     BTree *BT;
76     BT=CreateT();
77     if(PostOrder(BT)){
78         printf("\n后序遍历完成!\n");
79     }    
80     if(PostOrder2(BT)){
81         printf("\n非递归后序遍历完成!\n");
82     }
83 }

 //-------------------------华丽的分割线-------------------------------------

下面是我自己写的后序遍历程序

 1 //非递归后序遍历-test
 2 void PostOrder3(BTree *T){
 3     BTree *p=T;Stack s;s.top=-1;
 4     int tag[MaxSize];
 5     while(p||s.top!=-1){
 6         
 7         if(p){
 8             s.data[++s.top]=p;
 9             tag[s.top]=0;
10             p=p->lchild;
11         }        
12         else{
13             while(tag[s.top]==1){
14             p=s.data[s.top--];
15             printf("%d",p->data); 
16             }
17             p=s.data[s.top];
18             p=p->rchild;
19             tag[s.top]=1;
20         }
21         if(s.top==-1) break;
22     }
23 } 

 

转载于:https://www.cnblogs.com/geolike/p/4721799.html

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值