二叉树的先序,中序,后序,层次,递归,非递归遍历

     关于二叉树的遍历,递归遍历的话,就只要不断的递归就够啦,而非递归的话就需要用到栈和队列了,然而栈和队列也是我自己写的吧,就算是锻炼了一下自己对数据结构课的掌握吧,而非递归后序遍历二叉树参考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。

一、先序遍历二叉树

   1.递归遍历

    每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。

 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.非递归遍历

   判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。

 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 }

 

二、中序遍历二叉树

     1.递归遍历

      每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。

 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 }

三、后序遍历二叉树

    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 }

四、层次遍历二叉树

    建立一个队列,先将根节点入队,然后将队首出队,然后判断它的左右子树是否为空,不为空,则先将左子树入队,然后右子树入队。

 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

 

posted @ 2014-06-02 17:53  风xmx  阅读(24451)  评论(0编辑  收藏  举报