首先非常感谢‘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 }