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