遍历二叉树的递归算法与非递归算法

遍历二叉树的递归算法与非递归算法

 

先来看下面这棵二叉树。如图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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值