C++ 二叉樹的先序,中序,后序遍歷


 

 三種遍歷方式都分為遞歸與非遞歸的方式。三種遍歷方式的遞歸思想相同。后序遍歷非遞歸方法分為兩種,具體見代碼。

 

構造方式:

 1 #include<iostream>
 2 #include<stack>
 3 using namespace std;
 4 
 5 typedef struct BiTNode{
 6     char data;
 7     int lvisited,rvisited;//左、右孩子是否訪問過,1表示已訪問(此項只在后序非遞歸2算法中需要)
 8     struct BiTNode *lchild,*rchild;
 9 }BiTNode,*BiTree;
10 
11 void InitBiTree(BiTree &T)//構造空二叉樹
12 {
13     T=NULL;
14 }
15 void CreateBiTree(BiTree &T)//生成二叉樹
16 {
17     char ch;
18     cin>>ch;
19     if(ch=='0')//0代表空
20         T=NULL;
21     else
22     {
23         T=(BiTree)malloc(sizeof(BiTNode));//生成根結點
24         if(!T)
25         {
26             cout<<"生成結點錯誤!"<<endl;
27             return;
28         }
29         T->data=ch;
30         T->lvisited=0;
31         T->rvisited=0;
32         CreateBiTree(T->lchild);
33         CreateBiTree(T->rchild);
34     }
35 }

 

三種遍歷方式代碼:

  1 void PreOrder(BiTree T)//先序遞歸遍歷
  2 {
  3     if(T!=NULL)
  4     {
  5         cout<<T->data<<" ";
  6         PreOrder(T->lchild);
  7         PreOrder(T->rchild);
  8     }
  9 }
 10 void SqlPreOrder(BiTree T)//先序非遞歸遍歷
 11 {
 12     stack<BiTree> s;
 13     BiTree p=T;
 14     while(p || !s.empty())
 15     {
 16         if(p)
 17         {
 18             cout<<p->data<<" ";
 19             s.push(p);
 20             p=p->lchild;
 21         }
 22         else
 23         {
 24             p=s.top();
 25             p=p->rchild;
 26             s.pop();
 27         }
 28     }
 29 }
 30 
 31 
 32 
 33 void InOrder(BiTree T)//中序遞歸遍歷
 34 {
 35     if(T!=NULL)
 36     {
 37         InOrder(T->lchild);
 38         cout<<T->data<<" ";
 39         InOrder(T->rchild);
 40     }
 41 }
 42 void SqInOrder(BiTree T)//中序非遞歸遍歷
 43 {
 44     stack<BiTree> s;
 45     BiTree p=T;
 46     while(p || !s.empty())
 47         if(p)
 48         {
 49             s.push(p);
 50             p=p->lchild;
 51         }
 52         else
 53         {
 54             p=s.top();
 55             cout<<p->data<<" ";
 56             s.pop();
 57             p=p->rchild;
 58         }
 59 }
 60 
 61 
 62 
 63 void PostOrder(BiTree T)//后序遞歸遍歷
 64 {
 65     if(T!=NULL)
 66     {
 67         PostOrder(T->lchild);
 68         PostOrder(T->rchild);
 69         cout<<T->data<<" ";
 70     }
 71 }
 72 
 73 //后序非遞歸遍歷1思路:因為后序非遞歸遍歷二叉樹的順序是先訪問左子樹,再訪問后子樹,最后
 74 //訪問根結點。當用堆棧來存儲結點,必須分清返回根結點時,是從左子樹返回的,還是從右子樹
 75 //返回的。所以,使用輔助指針r,其指向最近訪問過的結點。
 76 void SqlPostOrder1(BiTree T)//后序非遞歸遍歷1
 77 {
 78     stack<BiTree> s;
 79     BiTree p=T,r;
 80     while(p || !s.empty())
 81     {
 82         if(p)                             //走到最左邊
 83         {
 84             s.push(p);
 85             p=p->lchild;
 86         }
 87         else                             //向右
 88         {
 89             p=s.top();//取棧頂結點
 90             if(p->rchild && p->rchild!=r)//如果右子樹存在,且未被訪問過
 91             {
 92                 p=p->rchild;
 93                 s.push(p);
 94                 p=p->lchild;             //再走到最左
 95             }
 96             else                         //否則,訪問棧頂結點並彈出
 97             {
 98                 cout<<p->data<<" ";
 99                 r=p;                     //記錄該結點
100                 s.pop();
101                 p=NULL;                     //結點訪問完后,重置p指針
102             }
103         }
104     }
105 }
106 //思路2:在結點中增加標志域,記錄是否已被訪問。
107 void SqlPostOrder2(BiTree T)//后序非遞歸遍歷2
108 {
109     stack<BiTree> s;
110     BiTree p=T;
111     while(p || !s.empty())
112     {
113         if(p && p->lvisited==0)                     //左走,且左子樹未被訪問
114         {
115             p->lvisited=1;
116             s.push(p);
117             p=p->lchild;
118         }
119         else
120         {
121             p=s.top();
122             if(p->rchild!=NULL && p->rvisited==0)//右子樹未被訪問,右走一步
123             {
124                 p->rvisited=1;
125                 p=p->rchild;
126             }
127             else                                 //訪問棧頂元素並彈棧
128             {
129                 cout<<p->data<<" ";
130                 s.pop();
131                 if(!s.empty())
132                     p=s.top();
133                 else                             //當最后一個元素彈棧出去后,結束
134                     return ;
135             }
136         }
137     }
138 }

 

轉載:http://aleeee.com/bitreetraveser1.html

 


免責聲明!

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



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