二叉樹的先序,中序,後序,層次,遞歸,非遞歸遍歷

     關於二叉樹的遍歷,遞歸遍歷的話,就只要不斷的遞歸就夠啦,而非遞歸的話就須要用到棧和隊列了,然而棧和隊列也是我本身寫的吧,就算是鍛鍊了一下本身對數據結構課的掌握吧,而非遞歸後序遍歷二叉樹參考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。html

1、先序遍歷二叉樹node

   1.遞歸遍歷c#

    每次先判斷是否爲空樹,若不是則訪問根節點,而後左子樹,最後右子樹。數據結構

 1 /*二叉樹遞歸先序遍歷*/
 2 void PreTraverseTree1(TreeNode * T)
 3 {
 4     if(T)
 5     {
 6         printf("%c  ", T->data) ;
 7         PreTraverseTree1(T->leftchild) ;
 8         PreTraverseTree1(T->rightchild) ;
 9     }
10 }

  2.非遞歸遍歷函數

   判斷棧是否爲空或子樹爲空,若不爲空,就訪問左孩子入棧,直至左孩子爲空,若左孩子爲空,就出棧,而後訪問右孩子,入棧,就這樣不斷的循環。spa

 1 /*二叉樹的非遞歸先序遍歷*/
 2 void PreTraverseTree2(TreeNode * T)
 3 {
 4     StackNode * S ;
 5     TreeNode * p ;
 6     S = NULL ;
 7     p = T ;
 8     S = InitStack(S) ;
 9 
10     if(NULL == p)
11     {
12         printf("樹爲空!\n") ;
13         return ;
14     }
15 
16     while(p || !StackEmpty(S))
17     {
18         if(p)
19         {
20             StackPush(S, p) ;
21             printf("%c  ", p->data) ;
22             p = p->leftchild ;
23         }
24         else
25         {
26             StackPop(S, p) ;
27             p = p->rightchild ;
28         }
29     }
30 
31     free(S) ;
32 }

 

2、中序遍歷二叉樹code

     1.遞歸遍歷htm

      每次先判斷樹是否爲空,若不爲空,則訪問左子樹,而後根子樹,最後右子樹。blog

 1 /*二叉樹遞歸中序遍歷*/
 2 void InOrderTraverseTree1(TreeNode * T)
 3 {
 4     if(T)
 5     {
 6         InOrderTraverseTree1(T->leftchild) ;
 7         printf("%c  ", T->data) ;
 8         InOrderTraverseTree1(T->rightchild) ;
 9     }
10 }

    2.非遞歸遍歷遞歸

    思路基本和先序差很少,只是輸出數據的時候不同。判斷棧和樹是否爲空,若不,則判斷樹是否爲空,不爲繼續將左子樹進棧,若爲空,則出棧,輸出數據,而後訪問右子樹。

 1 /*二叉樹的非遞歸中序遍歷*/
 2 void InOrderTraverseTree2(TreeNode * T)
 3 {
 4     StackNode * S ;
 5     TreeNode * p ;
 6     S = NULL ;
 7     p = T ;
 8     S = InitStack(S) ;
 9 
10     if(NULL == p)
11     {
12         printf("樹爲空!\n") ;
13         return ;
14     }
15 
16     while(p || !StackEmpty(S))
17     {
18         if(p)
19         {
20             StackPush(S, p) ;
21             p = p->leftchild ;
22         }
23         else
24         {
25             StackPop(S, p) ;
26             printf("%c  ", p->data) ;
27             p = p->rightchild ;
28         }
29     }
30     free(S) ;
31 }

3、後序遍歷二叉樹

    1.遞歸遍歷

    先判斷樹是否爲空,若不爲,先左子樹,後右子樹,而後根節點。

 1 /*二叉樹遞歸後序遍歷*/
 2 void LastTraverseTree1(TreeNode * T)
 3 {
 4     if(T)
 5     {
 6         LastTraverseTree1(T->leftchild) ;
 7         LastTraverseTree1(T->rightchild) ;
 8         printf("%c  ", T->data) ;
 9     }
10 }

    2.非遞歸遍歷

     要保證根結點在左孩子和右孩子訪問以後才能訪問,所以對於任一結點P,先將其入棧。若是P不存在左孩子和右孩子,則能夠直接訪問它;或者P存在左孩子或者右孩子,可是其左孩子和右孩子都已被訪問過了,則一樣能夠直接訪問該結點。若非上述兩種狀況,則將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。

 1 /*二叉樹非遞歸後序遍歷*/
 2 void LastTraverseTree2(TreeNode * T)
 3 {
 4     StackNode * S ;
 5     TreeNode * cur, * pre ;
 6     S = NULL ;
 7     S = InitStack(S) ;
 8     if(NULL == T)
 9     {
10         printf("樹爲空!\n") ;
11         return ;
12     }
13 
14     pre = NULL ;    cur = NULL ;
15     StackPush(S,T) ;
16     while(!StackEmpty(S))
17     {
18         cur = NULL ;
19         StackGetTop(S,cur) ;
20         if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
21         {
22             printf("%c  ", cur->data) ;
23             pre = cur ;
24             StackPop(S,cur) ;
25         }
26         else
27         {
28             if(cur->rightchild != NULL)
29             {
30                 StackPush(S,cur->rightchild) ;
31             }
32             if(cur->leftchild != NULL)
33             {
34                 StackPush(S,cur->leftchild) ;
35             }
36         }
37     }
38     free(S) ;
39 }

4、層次遍歷二叉樹

    創建一個隊列,先將根節點入隊,而後將隊首出隊,而後判斷它的左右子樹是否爲空,不爲空,則先將左子樹入隊,而後右子樹入隊。

 1 /*二叉樹層次遍歷*/
 2 void LevelTraverseTree(TreeNode * T)
 3 {
 4     QueueHead * Q ;
 5     TreeNode * p ;
 6     Q = NULL ;    p = T ;
 7     Q = InitQueue(Q) ;
 8     if(NULL == p)
 9     {
10         printf("樹爲空!\n") ;
11         return ;
12     }
13 
14     QueuePush(Q,p) ;
15     while(!QueueEmpty(Q))
16     {
17         p = NULL ;
18         QueuePop(Q,p) ;
19 
20         if(NULL != p->leftchild)
21             QueuePush(Q,p->leftchild) ;
22 
23         if(NULL != p->rightchild)
24             QueuePush(Q,p->rightchild) ;
25 
26         printf("%c  ", p->data) ;
27     }
28 }

 

 

貼上我本身的所有代碼,本身之後能夠看,但願或許對別人也有幫助吧,表達能力不行,嘿嘿。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef struct treenode      //樹的節點
  5 {
  6     char data ;
  7     treenode * leftchild, * rightchild ;
  8 }TreeNode;
  9 
 10 typedef TreeNode * StackElemType ;   //定義棧包含的數據類型
 11 
 12 typedef struct stacknode    //棧的節點
 13 {
 14     StackElemType data ;
 15     stacknode * next ;
 16 }StackNode;
 17 
 18 typedef TreeNode * QueueElemType ;     //定義隊列包含的數據類型
 19 
 20 typedef struct queuenode     //定義隊列節點
 21 {
 22     QueueElemType  data ;
 23     struct queuenode * next ;
 24 }QueueNode;
 25 
 26 typedef struct queuehead    //定義隊列的頭節點
 27 {
 28     QueueNode * front, * rear ;
 29 }QueueHead;
 30 
 31 //stack的有關聲明
 32 StackNode * InitStack(StackNode * S) ;
 33 void StackPush(StackNode * S, StackElemType data) ;
 34 void StackPop(StackNode * S, StackElemType & data) ;
 35 int StackEmpty(StackNode * S) ;
 36 int StackGetTop(StackNode * S, StackElemType & data) ;
 37 
 38 //queue的有關聲明
 39 QueueHead * InitQueue(QueueHead * Q) ;
 40 void QueuePush(QueueHead * Q, QueueElemType data) ;
 41 void QueuePop(QueueHead * Q, QueueElemType & data) ;
 42 int QueueEmpty(QueueHead * Q) ;
 43 
 44 //TreeTraverse的有關聲明
 45 TreeNode * InitTree(TreeNode * T) ;
 46 void PreTraverseTree1(TreeNode * T) ;
 47 void PreTraverseTree2(TreeNode * T) ;
 48 void InOrderTraverseTree1(TreeNode * T) ;
 49 void InOrderTraverseTree2(TreeNode * T) ;
 50 void LastTraverseTree1(TreeNode * T) ;
 51 void LastTraverseTree2(TreeNode * T) ;
 52 void LevelTraverseTree(TreeNode * T) ;
 53 
 54 //棧的函數定義
 55 StackNode * InitStack(StackNode * S)
 56 {
 57     S = (StackNode *)malloc(sizeof(StackNode)) ;
 58     if(NULL == S)
 59     {
 60         printf("內存不足,不能分配棧!\n") ;
 61         exit(0) ;
 62     }
 63 
 64     S->next = NULL ;
 65     return(S) ;
 66 }
 67 
 68 void StackPush(StackNode * S, StackElemType data)
 69 {
 70     StackNode * q ;
 71     q = (StackNode *)malloc(sizeof(StackNode)) ;
 72     if(NULL == q)
 73     {
 74         printf("內存不足,不能分配棧!\n") ;
 75         exit(0) ;
 76     }
 77     q->data = data ;
 78     q->next = S->next ;
 79     S->next = q ;
 80 }
 81 
 82 void StackPop(StackNode * S, StackElemType & data)
 83 {
 84     StackNode * q ;
 85     if(NULL == S->next)
 86     {
 87         printf("棧爲空,無返回值!\n") ;
 88     }
 89 
 90     q = S->next ;
 91     data = q->data ;
 92     S->next = q->next ;
 93     free(q) ;
 94 }
 95 
 96 int StackEmpty(StackNode * S)
 97 {
 98     if(NULL == S->next)
 99     {
100         return(1) ;
101     }
102 
103     return(0) ;
104 }
105 
106 int StackGetTop(StackNode * S, StackElemType & data)
107 {
108     if(NULL != S->next)
109     {
110         data = S->next->data ;
111         return(1) ;
112     }
113     else
114     {
115         //data = NULL ;
116         return(0) ;
117     }
118 }
119 
120 
121 //隊列函數的定義
122 QueueHead * InitQueue(QueueHead * Q)
123 {
124     QueueNode * q ;
125     Q = (QueueHead *)malloc(sizeof(QueueHead)) ;
126     if(NULL == Q)
127     {
128         printf("內存不足!\n") ;
129         exit(0) ;
130     }
131     q = (QueueNode *)malloc(sizeof(QueueNode)) ;
132     if(NULL == q)
133     {
134         printf("內存不足!\n") ;
135         exit(0) ;
136     }
137 
138     q->next = NULL ;
139     Q->front = q ;
140     Q->rear = q ;
141 
142     return(Q) ;
143 }
144 
145 void QueuePush(QueueHead * Q, QueueElemType data)
146 {
147     QueueNode * q ;
148     q = (QueueNode *)malloc(sizeof(QueueNode)) ;
149     if(NULL == q)
150     {
151         printf("內存不足!\n") ;
152         exit(0) ;
153     }
154 
155     q->data = data ;
156     q->next = Q->rear->next ;
157     Q->rear->next = q ;
158     Q->rear = q ;
159 }
160 
161 void QueuePop(QueueHead * Q, QueueElemType & data)
162 {
163     QueueNode * q ;
164     if(Q->front == Q->rear)
165     {
166         printf("隊列爲空!\n") ;
167         return ;
168     }
169 
170     q = Q->front->next ;
171     data = q->data ;
172     Q->front->next = q->next ;
173     if(Q->rear == q)
174         Q->rear = Q->front ;
175 
176     free(q) ;
177 }
178 
179 int QueueEmpty(QueueHead * Q)
180 {
181     if(Q->front == Q->rear)
182         return(1) ;
183     else
184         return(0) ;
185 }
186 
187 
188 //樹的各類遍歷函數定義
189 
190 /*創建一棵二叉樹*/
191 TreeNode * InitTree(TreeNode * T)
192 {
193     char data ;
194     scanf("%c", &data) ;
195 
196     if('#' == data)
197     {
198         T = NULL ;
199     }
200     else
201     {
202         T = (TreeNode *)malloc(sizeof(TreeNode)) ;
203         T->data = data ;
204         T->leftchild = InitTree(T->leftchild) ;
205         T->rightchild = InitTree(T->rightchild) ;
206     }
207 
208     return(T) ;
209 }
210 
211 /*二叉樹遞歸先序遍歷*/
212 void PreTraverseTree1(TreeNode * T)
213 {
214     if(T)
215     {
216         printf("%c  ", T->data) ;
217         PreTraverseTree1(T->leftchild) ;
218         PreTraverseTree1(T->rightchild) ;
219     }
220 }
221 
222 /*二叉樹的非遞歸先序遍歷*/
223 void PreTraverseTree2(TreeNode * T)
224 {
225     StackNode * S ;
226     TreeNode * p ;
227     S = NULL ;
228     p = T ;
229     S = InitStack(S) ;
230 
231     if(NULL == p)
232     {
233         printf("樹爲空!\n") ;
234         return ;
235     }
236 
237     while(p || !StackEmpty(S))
238     {
239         if(p)
240         {
241             StackPush(S, p) ;
242             printf("%c  ", p->data) ;
243             p = p->leftchild ;
244         }
245         else
246         {
247             StackPop(S, p) ;
248             p = p->rightchild ;
249         }
250     }
251 
252     free(S) ;
253 }
254 
255 /*二叉樹遞歸中序遍歷*/
256 void InOrderTraverseTree1(TreeNode * T)
257 {
258     if(T)
259     {
260         InOrderTraverseTree1(T->leftchild) ;
261         printf("%c  ", T->data) ;
262         InOrderTraverseTree1(T->rightchild) ;
263     }
264 }
265 
266 /*二叉樹的非遞歸中序遍歷*/
267 void InOrderTraverseTree2(TreeNode * T)
268 {
269     StackNode * S ;
270     TreeNode * p ;
271     S = NULL ;
272     p = T ;
273     S = InitStack(S) ;
274 
275     if(NULL == p)
276     {
277         printf("樹爲空!\n") ;
278         return ;
279     }
280 
281     while(p || !StackEmpty(S))
282     {
283         if(p)
284         {
285             StackPush(S, p) ;
286             p = p->leftchild ;
287         }
288         else
289         {
290             StackPop(S, p) ;
291             printf("%c  ", p->data) ;
292             p = p->rightchild ;
293         }
294     }
295     free(S) ;
296 }
297 
298 /*二叉樹遞歸後序遍歷*/
299 void LastTraverseTree1(TreeNode * T)
300 {
301     if(T)
302     {
303         LastTraverseTree1(T->leftchild) ;
304         LastTraverseTree1(T->rightchild) ;
305         printf("%c  ", T->data) ;
306     }
307 }
308 
309 /*二叉樹非遞歸後序遍歷*/
310 void LastTraverseTree2(TreeNode * T)
311 {
312     StackNode * S ;
313     TreeNode * cur, * pre ;
314     S = NULL ;
315     S = InitStack(S) ;
316     if(NULL == T)
317     {
318         printf("樹爲空!\n") ;
319         return ;
320     }
321 
322     pre = NULL ;    cur = NULL ;
323     StackPush(S,T) ;
324     while(!StackEmpty(S))
325     {
326         cur = NULL ;
327         StackGetTop(S,cur) ;
328         if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
329         {
330             printf("%c  ", cur->data) ;
331             pre = cur ;
332             StackPop(S,cur) ;
333         }
334         else
335         {
336             if(cur->rightchild != NULL)
337             {
338                 StackPush(S,cur->rightchild) ;
339             }
340             if(cur->leftchild != NULL)
341             {
342                 StackPush(S,cur->leftchild) ;
343             }
344         }
345     }
346     free(S) ;
347 }
348 
349 /*二叉樹層次遍歷*/
350 void LevelTraverseTree(TreeNode * T)
351 {
352     QueueHead * Q ;
353     TreeNode * p ;
354     Q = NULL ;    p = T ;
355     Q = InitQueue(Q) ;
356     if(NULL == p)
357     {
358         printf("樹爲空!\n") ;
359         return ;
360     }
361 
362     QueuePush(Q,p) ;
363     while(!QueueEmpty(Q))
364     {
365         p = NULL ;
366         QueuePop(Q,p) ;
367 
368         if(NULL != p->leftchild)
369             QueuePush(Q,p->leftchild) ;
370 
371         if(NULL != p->rightchild)
372             QueuePush(Q,p->rightchild) ;
373 
374         printf("%c  ", p->data) ;
375     }
376 }
377 
378 
379 //主函數的定義
380 void Tips()
381 {
382     printf("創建樹是按照先序遍從來創建樹的,而且輸入‘#’表示子樹爲空。\n") ;
383     printf("請輸入要創建的樹:") ;
384 }
385 
386 int main()
387 {
388     TreeNode * T ;
389     T = NULL ;
390 
391     Tips() ;
392 
393     T = InitTree(T) ;
394 
395     printf("二叉樹遞歸先序遍歷\n") ;
396     PreTraverseTree1(T) ;
397     printf("\n") ;
398 
399     printf("二叉樹非遞歸先序遍歷\n") ;
400     PreTraverseTree2(T) ;
401     printf("\n") ;
402 
403     printf("二叉樹遞歸中序遍歷\n") ;
404     InOrderTraverseTree1(T) ;
405     printf("\n") ;
406 
407     printf("二叉樹非遞歸中序遍歷\n") ;
408     InOrderTraverseTree2(T) ;
409     printf("\n") ;
410 
411     printf("二叉樹遞歸後序遍歷\n") ;
412     LastTraverseTree1(T) ;
413     printf("\n") ;
414 
415     printf("二叉樹非遞歸後序遍歷\n") ;
416     LastTraverseTree2(T) ;
417     printf("\n") ;
418 
419     printf("二叉樹層次遍歷\n") ;
420     LevelTraverseTree(T) ;
421     printf("\n") ;
422 
423     return 0 ;
424 }

 

給一個二叉樹參考例子:

                             a

                       b          c

                d            e

輸入:abd##e##c##

輸出:

二叉樹先序遞歸遍歷:a  b  d  e  c

二叉樹先序非遞歸遍歷:a  b  d  e  c

二叉樹中序遞歸遍歷:d  b  e  a  c

二叉樹中序非遞歸遍歷:d  b  e  a  c

二叉樹後序遞歸遍歷:d  e  b  c  a

二叉樹後序非遞歸遍歷:d  e  b  c  a

二叉樹層次遍歷:a  b  c  d  e

相關文章
相關標籤/搜索