遍历二叉树的递归算法与非递归算法以及C语言实现

zz http://blog.csdn.net/fuzhufang/archive/2009/03/08/3969375.aspx

 

先来看下面这棵二叉树。如图 1 。现在我们要对它进行先序遍历。递归思想:就是把这个大树拆分成 N 棵小树,每棵小树都进行一次先序遍历。再把这些遍历连合起来就是这棵树的先序遍历了。同理中序遍历和后序遍历也是一样的方法。下面举例说明先序递归算法:

令先序遍历的结果等于 S

 

                     1

 

对于图 2 这棵小树的先序遍历是: 1    2     3

S = 1       2      3

 

              2

 

 

但以 2 为根节点又有一棵小树,这棵小树的先序遍历是: 2    4     5

S = 1       2      4      5      3

 

       3

 

 

3 为根节点又有一棵小树,这棵小树的先序遍历是: 3       6     7

S = 1       2      4      5      3      6      7

 

       4

 

 

6 为根节点又有一棵小树,这个小树的先序遍历是: 6       7    

S =1              2      4      5      3      6      8      7

 

       5

 

7 为跟节点又有一棵小树,这棵小树的先序遍历是: 7       9

S = 1      2      4      5      3      6      8      7     9

 

       6

 

这样就得出了这棵大树的最终先序遍历结果了:

S = 1      2      4      5      3      6      8      7     9

再来看看这个变化过程:

S = 1       2      3

S = 1       2      4      5      3

S = 1       2      4      5      3      6      7

S =1              2      4      5      3      6      8      7

S = 1      2      4      5      3      6      8      7     9

 

 

对于二叉树的非递归算法,则是需要应用一种重要的数据结构 栈。用栈来存放准备需要访问的节点。例如先序遍历的非递归算法则是:

指针 p 指向根节点;

while p 不为 NULL 或栈不空){

       反复访问当前节点 *p

指针 p 进栈、再将指针左移,直至最左下节点;

当栈不空时,出栈,

取出栈顶指针且右移(返回上面操作,去遍历右子树);

 

下面是二叉树递归与非递归算法的 C 语言实现实例:

 

//tree.h

#ifndef __TREE_H__

#define __TREE_H__

 

typedef struct _node {

       struct _node * left_child ;

       struct _node * right_child ;

       ctype_t     data ;

} node , * tree ; // 二叉树节点结构

 

// 一种简单创建树的办法,供测试使用

void create_tree ( tree * root , const ctype_t elems [], csize_t * current_index , const csize_t max_size );

// 不考虑二叉树的销毁了

 

// 二叉树先序遍历递归算法

void preorder_recursion ( tree root );

 

// 二叉树先序遍历递非归算法

void preorder_nonrecursive ( tree root );

 

// 二叉树中序遍历递归算法

void inorder_recursion ( tree root );

 

// 二叉树中序遍历递非归算法

void inorder_nonrecursive ( tree root );

 

// 二叉树后序遍历递归算法

void postorder_recursion ( tree root );

 

// 二叉树后序遍历递非归算法

void postorder_nonrecursive ( tree root );

 

#endif //__TREE_H__

 

 

//tree.c

#include "tree.h"

void create_tree ( tree * root , const ctype_t elems [], csize_t * current_index , const csize_t max_size )

{

       if (* current_index < max_size )

       {

              const ctype_t t = elems [(* current_index )++];

              if ( 0 == t )

              {

                     * root = NULL ;

                     return ;

              }

              else

              {

                     * root = ( node *) malloc ( sizeof ( node )); // 假设 malloc 总是成功

                     (* root )-> data = t ;

                     create_tree (&(* root )-> left_child , elems , current_index , max_size );

                     create_tree (&(* root )-> right_child , elems , current_index , max_size );

              }

       }

}

 

void preorder_recursion ( tree root )

{

       if ( NULL != root )

       {

              printf ( "%d/t" , root -> data );            //

              preorder_recursion ( root -> left_child );    // 左子树

              preorder_recursion ( root -> right_child );  // 右子树

       }

}

 

void preorder_nonrecursive ( tree root )

{

       tree stack [ 100 ];

       int top = 0 ;

       tree p = root ;

       while ( NULL != p || top > 0 )

       {

              while ( NULL != p )

              {

                     printf ( "%d/t" , p -> data );

                     stack [ top ++] = p ;

                     p = p -> left_child ;

              }

              p = stack [-- top ];

              p = p -> right_child ;

       }

}

 

void inorder_recursion ( tree root )

{

       if ( NULL != root )

       {

              inorder_recursion ( root -> left_child );             // 左子树

              printf ( "%d/t" , root -> data );            //

              inorder_recursion ( root -> right_child );    // 右子树

       }

}

 

void inorder_nonrecursive ( tree root )

{

       tree stack [ 100 ];

       int top = 0 ;

       tree p = root ;

       while ( NULL != p || top > 0 )

       {

              while ( NULL != p )

              {

                     stack [ top ++] = p ;

                     p = p -> left_child ;

              }

 

              p = stack [-- top ];

              printf ( "%d/t" , p -> data );

              p = p -> right_child ;

       }

}

 

void postorder_recursion ( tree root )

{

       if ( NULL != root )

       {

              postorder_recursion ( root -> left_child );

              postorder_recursion ( root -> right_child );

              printf ( "%d/t" , root -> data );

       }

}

 

void postorder_nonrecursive ( tree root )

{

       tree stack [ 100 ];

       int top = 0 ;

       tree p = root ;

       tree lastvist = NULL ;

       while ( NULL != p || top > 0 )

       {

              while ( NULL != p )

              {

                     stack [ top ++] = p ;

                     p = p -> left_child ;

              }

 

              p = stack [ top - 1 ];

              if ( NULL == p -> right_child || lastvist == p -> right_child )

              {

                     printf ( "%d/t" , p -> data );

                     -- top ;

                     lastvist = p ;

                     p = NULL ;

              }

              else

              {

                     p = p -> right_child ;

              }

       }

}

 

//main.c

#include "tree.h"

int main ()

{

ctype_t elems [] = { 1 , 2 , 4 , 0 , 0 , 5 , 0 , 0 , 3 , 6 , 8 , 0 , 0 , 0 , 7 , 0 , 9 , 0 , 0 , 0 ,};

       csize_t current_index = 0 ;

       tree t = NULL ;

       create_tree (& t , elems , & current_index , sizeof ( elems ));

      

       printf ( " 二叉树先序遍历递归算法 /n" );

       preorder_recursion ( t );

       printf ( "/n" );

       printf ( " 二叉树先序遍历非递归算法 /n" );

       preorder_nonrecursive ( t );

 

       printf ( "/n/n" );

       printf ( " 二叉树中序遍历递归算法 /n" );

       inorder_recursion ( t );

       printf ( "/n" );

       printf ( " 二叉树中序遍历非递归算法 /n" );

       inorder_nonrecursive ( t );

 

       printf ( "/n/n" );

       printf ( " 二叉树后序遍历递归算法 /n" );

       postorder_recursion ( t );

       printf ( "/n" );

       printf ( " 二叉树后序遍历非递归算法 /n" );

       postorder_nonrecursive ( t );

       printf ( "/n" );

       return 0 ;

}

 

输出结果:

二叉树先序遍历递归算法

1       2       4       5       3       6       8       7       9

二叉树先序遍历非递归算法

1       2       4       5       3       6       8       7       9

 

二叉树中序遍历递归算法

4       2       5       1       8       6       3       7       9

二叉树中序遍历非递归算法

4       2       5       1       8       6       3       7       9

 

二叉树后序遍历递归算法

4       5       2       8       6       9       7       3       1

二叉树后序遍历非递归算法

4       5       2       8       6       9       7       3       1

Press any key to continue

 

=================

 

zz http://blog.pfan.cn/byoneself/19799.html

 

 PreOrder(BiTree T)   //先序非递归遍历二叉树

 {

          InitStack(S);  //创建工作栈

          Push(S,T);

          while(!StackEmpty(S))

          {

                    Pop(S,p);  //出栈

                    Visit(p);   //访问

                    if(p->rchild)

                              Push(S,p->rchild);  //右子树入栈

                    if(p->lchild)

                         Push(S,p->lchild);   //左子树入栈

          }

}

 

InOrder(BiTree T)   //中序非递归遍历二叉树

 {

          InitStack(S);  //创建工作栈

          Push(S,<T,0>);   //根入栈,且置0标志此时不能访问

          while(!StackEmpty(S))

          {

                    Pop(S,<p,flag>);  //出栈

                    if(flag==1)

                               Visit(p);  //访问标志为1可以访问

                     else

                     {

                           if(p->rchild)

                               Push(S,<p->rchild,0>);   //右子树入栈且置访问标志0

                            Push(S,<p,1>);   //根入栈且置访问标志1

                             if(p->lchild)

                                  Push(S,<p->lchild,0>);    //左子树入栈且置访问标志0

                      }

          }

}

 

PostOrder(BiTree T)   //后序非递归遍历二叉树

 {

          InitStack(S);  //创建工作栈

          Push(S,<T,0>);  //根入栈,且置i0标志此时不能访问

          while(!StackEmpty(S))

          {

                Pop(S,<p,flag>);  //出栈

                 if(flag==1)  

                          Visit(p);  //访问标志为1可以访问

                  else

                  {

                         Push(S,<p,1>);  //根入栈且置访问标志1

                           if(p->rchild)

                                  Push(S,<p->rchild,0>);  //右子树入栈且置访问标志0

                            if(p->lchild)

                                    Push(S,<p->lchild,0>);  //左子树入栈且置访问标志0

                   }

         }

}

 

LayerOrder(BiTree T)   //层次遍历二叉树

 {

          InitQueue(Q);  //创建工作队列

          EnQueue(Q,T);  //根入队

          while(!QueueEmpty(Q))

          {

                    DeQueue(Q,p);  //出队

                    Visit(p);  //访问

                    if(p->lchild) 

                              EnQueue(Q,p->lchild);  //左子树入队

                    if(p->rchild)

                              EnQueue(Q,p->rchild);    //右子树入队

          }

}

 

===

 

其他:

 

1  

二叉树遍历及C语言实现

2

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值