递归非递归两种算法遍历二叉树讲解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、设计思想
1. 用递归算法遍历
设计思想:主要是通过不同程序顺序,从而实现递归的顺序遍历
前序遍历:先判断节点是否为空,如果不为空,则输出。再判断左节点是否为空,如果不为空,则递归调用,直到遍历到最左边。接着再遍历最左边的右子树,如果此时右子树不为空,则递归遍历左子树的操作,直到遍历到叶子节点。如果右子树为空,则回溯上次的递归调用,重复输出和遍历右子树的操作。
中序遍历:先遍历左节点是否为空,如果不为空,则递归调用,直到遍历到最左边或者叶子节点,然后输出,接着再遍历最左边的右子树,如果此时右子树不为空,则递归重复遍历左子树的操作,直到遍历到叶子节点。如果右子树为空,则回溯到上次递归调用,重复输出和遍历右子树的操作。
后序遍历:先判断左节点是否为空,如果不为空则一直递归直到遍历到最左边,然后遍历右节点,再接着遍历到左子树的最右边,直到遍历到叶子节点。此时输出,回溯到上次递归,继续执行后面的操作,重复,直到将整个树遍历完毕。
2. 用非递归算法遍历
设计思想:主要是通过栈的存取,判空,从而实现树的遍历
前序遍历:通过一个循环实现。先输出节点的数值,因为栈的特性,则需要先判断右子树是否为空,如果不为空,则将右子树压栈。然后判断左子树是否为空,如果不为空,则将左子树压栈。接着再将栈里面的子树弹出赋给给当前节点变量,重复上述操作,直到栈为空后退出循环。
中序遍历:通过循环实现。将树一直遍历到最左端,并将中间所经过的节点保存在栈中,当遍历到最左边的时候,则弹出栈里面的子树。输出数值,将当前节点赋值为当前节点的右子树,遍历右子树,即重复上述操作,直到当前节点为空,并且栈内元素为0。
后序遍历:通过循环和标记栈实现。将数一直遍历到最左端,并将中间的节点保存在树栈中,同时同步的添加一个标记栈。当遍历到最左边的时候,弹栈并赋值给当前栈,然后判断标记栈的数值,如果数值为0的话则代表当前树没有遍历过,遍历右子树。然后重复上面的操作,如果数值为1的话则代表此时数已经遍历过了,可以开始输出了,为了避免重复输出,将当前栈赋为空。重复循环操作,直到栈内没有元素,且当前节点为空(因为一直左的操作并没有将右子树压栈)。
二、算法流程图
图1 递归算法-先序遍历 图2 递归算法-后序遍历 图3 递归算法-中序遍历
图4 非递归算法-先序遍历 图5 非递归算法-中序遍历
图6 非递归算法-后序遍历
三、源代码
#include
#include
typedef char ElemType;
//定义树结构
typedef struct tree
{
ElemType data;
struct tree * lchild;
struct tree * rchild;
unsigned int isOut; //专为后序遍历设置的,0为不需要被输出,1为需要被输出}TreeNode, *Tree;
//定义栈结构
typedef struct stack
{
Tree * base;
Tree * top;
int stacksize;
}SqStack;
void InitStack( SqStack &s );
void Push( SqStack &s, Tree e );
void GetTop( SqStack s, Tree &e );
void Pop( SqStack &s, Tree &e );
int StackEmpty( SqStack s );
void CreateTree(Tree &t);
void PreOrder(Tree t);
void PreOrder1(Tree t);
void InOrder(Tree t);
void InOrder1(Tree t);
void PostOrder(Tree t);
void PostOrder1(Tree t);
int main()
{
Tree T;
printf("\n按先序序列输入结点序列,'*'代表空:");
CreateTree(T);
printf("\n 递归先序遍历的结果:");
PreOrder(T);
printf("\n非递归先序遍历的结果:");
PreOrder1(T);
printf("\n 递归中序遍历的结果:");
InOrder(T);
printf("\n非递归中序遍历的结果:");
InOrder1(T);
printf("\n 递归后序遍历的结果:");
PostOrder(T);
printf("\n非递归后序遍历的结果:");
PostOrder1(T);
printf("\n");
return 0;
}
void InitStack( SqStack &s ) //初始化栈
{
s.base = (Tree *)malloc(100*sizeof(Tree));
if ( !s.base )
{
printf("InitStack内存分配出错,程序将推出执行!\n");
exit (-1);
}
s.top = s.base;
s.stacksize = 100;
}
void Push (SqStack &s, Tree e ) //元素入栈接收一个stack 类型变量和一个tree* 类型变量{
if ( s.top - s.base >= s.stacksize )
{
s.base = (Tree *)realloc(s.base,(s.stacksize+20)*sizeof(Tree));
if ( !s.base )
{
printf("Push内存分配出错,程序将退出执行\n");
exit (-1);
}
s.top = s.base + s.stacksize; //
s.stacksize += 20;
}
e->isOut = 0;
*s.top++ = e;
}
void GetTop( SqStack s, Tree &e ) //获得栈顶元素