二叉樹后序遍歷的非遞歸算法(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 } 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM