二叉树的遍历是对二叉树操作的基础。由于二叉树是递归定义的所以我们很容易想到一个递归的算法遍历二叉树,那么我们能不能写出一个非递归的算法来对二叉树进行遍历呢?答案是一定的。下面我就说一下我实现非递归算法的想法。在实现非递归的算法时,我们是让树的根节点依次的进栈,然后再出栈。那么一个很自然的问题就是树的根节点要什么时候入栈?什么时候出栈?下面是我的实现代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <vector>
using namespace std;
typedef struct node
{
char str, flag;
struct node * lchild, * rchild;
}Tree_Node;
void build_Tree(Tree_Node* & root)
{
//使用先序遍历的算法建立一棵二叉树:
char c;
scanf("%c",&c);
if(c == '#')return;
//建立一个树节点:
Tree_Node *tmp_Node = (Tree_Node *)malloc(1*sizeof(Tree_Node));
tmp_Node->str = c; tmp_Node->flag = '\0';
tmp_Node->lchild = tmp_Node->rchild = NULL;
root = tmp_Node;
//递归的建立左子树:
build_Tree(tmp_Node->lchild);
//递归的建立右子树:
build_Tree(tmp_Node->rchild);
}
void PreOrderTraverse_recursive(Tree_Node * root)
{
if(root == NULL)return;
printf("%c",root->str);
PreOrderTraverse_recursive(root->lchild);
PreOrderTraverse_recursive(root->rchild);
}
void InOrderTraverse_recursive(Tree_Node * & root)
{
if(root == NULL)return;
InOrderTraverse_recursive(root->lchild);
printf("%c",root->str);
InOrderTraverse_recursive(root->rchild);
}
void NextOrderTraverse_recursive(Tree_Node * root)
{
if(root == NULL)return;
NextOrderTraverse_recursive(root->lchild);
NextOrderTraverse_recursive(root->rchild);
printf("%c",root->str);
}
void PreOrderTraverse_no_recursive(Tree_Node * root)
{
stack<Tree_Node *> S; S.push(root);
while(!S.empty())
{
Tree_Node * tmp = S.top();
if(tmp == NULL)S.pop();
else if(tmp->flag == '\0')
{
printf("%c",tmp->str);
tmp->flag = 'l';
S.push(tmp->lchild);
}
else if(tmp->flag == 'l')
{
tmp->flag = 'r';
S.push(tmp->rchild);
}
else if(tmp->flag == 'r')
{
S.pop(); tmp->flag = '\0';
}
}
}
void InOrderTraverse_no_recursive(Tree_Node * & root)
{
stack<Tree_Node * > S;
Tree_Node * tmp;
S.push(root);
while(!S.empty())
{
while((tmp = S.top()) && tmp)S.push(tmp->lchild); //向左走到尽头;
S.pop();
if(!S.empty())
{
tmp = S.top(); S.pop();
printf("%c",tmp->str);
S.push(tmp->rchild);
}
}
}
void NextOrderTraverse_no_recursive(Tree_Node * root)
{
stack<Tree_Node *> S; S.push(root);
Tree_Node * tmp = NULL;
while(!S.empty())
{
tmp = S.top();
if(tmp == NULL)S.pop();
else if(tmp->flag == '\0')
{
tmp->flag = 'l';
S.push(tmp->lchild);
}
else if(tmp->flag == 'l')
{
tmp->flag = 'r';
S.push(tmp->rchild);
}
else
{
printf("%c",tmp->str); tmp->flag = '\0';
S.pop();
}
}
}
int main()
{
Tree_Node * root;
build_Tree(root);
printf("递归实现的先序遍历:\n");
PreOrderTraverse_recursive(root);
printf("\n");
printf("非递归实现的先序遍历:\n");
PreOrderTraverse_no_recursive(root);
printf("\n");
printf("递归实现的中序遍历:\n");
InOrderTraverse_recursive(root);
printf("\n");
printf("非递归实现的中序遍历:\n");
InOrderTraverse_no_recursive(root);
printf("\n");
printf("递归实现的后序遍历:\n");
NextOrderTraverse_recursive(root);
printf("\n");
printf("非递归实现的后序遍历:\n");
NextOrderTraverse_no_recursive(root);
printf("\n");
return 0;
}