用递归,非递归两种方法遍历二叉树
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、设计思想
递归实现二叉树遍历的思想:
1.要遍历二叉树首先的问题是创建二叉树。二叉树的创建可以采用很多的方法。例如:先序,中序,后序,还可以采用层次的方法创建二叉树。本程序采用的是先序递归的方式创建的二叉树。
2.然后是中序,先序,后序递归遍历二叉树。递归的思想是一直调用方法本身。
3.中序递归遍历二叉树的思想是先访问左子树,然后访问根节点,最后访问右子树。当访问左子树或是右子树的时候,实际上调用的是函数本身。在这里就体现了递归的思想,当函数的返回值是0的时候,则返回上一次的程序,继续执行下面的语句。
4.先序递归遍历二叉树的思想是先访问根节点,然后访问左子树,最后访问右子树。同样如步骤3的方式相同,当访问左子树或者是右子树的收,实际上调用的是函数本身,直到返回值是0的时候,返回上一层的程序继续执行。
5.后序递归遍历二叉树的思想是先访问左子树,然后访问右子树,最后访问根节点。
同样跟步骤3的方式相同,当访问左子树或者右子树的时候实际上是调用的是方法本直到有返回值的时候才返回上一层的程序,继续执行.
非递归实现二叉树遍历的思想:
1.跟递归遍历二叉树的前提一样,首先应该创建一个二叉树,同样使用先序递归的方式创建二叉树。
2.然后是中序,先序,后序非递归遍历二叉树。
3.中序非递归遍历二叉树的思想是:首先是根节点压栈,当根节点的左子树不是空的时候,左子树压栈。直到左子树为空的时候,不再压栈。将栈顶元素出栈,访问栈顶元素,并将栈顶的右子树进栈。当右子树的左子树不是空的时候,左子树一直进栈,直到左子树为空,则不再进栈。重复上面的操作,直到栈空的时候。
4.先序非递归遍历二叉树的思想是:首先是根节点进栈,然后当栈不为空的时候,将栈顶元素出栈,然后访问。同时将出栈元素的右子树进栈,左子树进栈。重复上面的操作,直到栈为空。
5.后序非递归遍历二叉树的思想:首先是根节点进栈,当根节点的左子树不为空的时候,左子树进栈,直到左为空的时候,左子树不再进栈。指针指向的是右子树,当右子树为空的时候,直接访问根节点。当右子树不为空的时候,则右子树的指针进栈,当右子树的左子树不为空的时候,则左也进栈,直到左为空。重复上面的操作,直到栈为空的时候,则遍历树完成。
二、算法流程图
递归方法遍历二叉树的流程图如图1
图1 递归方法遍历二叉树流程图
非递归先序遍历二叉树流程图
图2:非递归先序遍历二叉树流程图
后序非递归遍历二叉树流程图如图3
图3 后序非递归遍历二叉树流程图
中序非递归遍历二叉树流程图4
图4:中序非递归遍历二叉树流程
三、源代码
用递归的方式实现二叉树的遍历
#include "stdio.h"
#include "conio.h"
#include
/*定义二叉树*/
typedef struct node{
char data;
struct node *lchild, *rchild;
}BinTnode;
typedef BinTnode * BinTree; //定义二叉树类型的指针
/*先序创建二叉树*/
int CreateBinTree(BinTree *T){ /*BinTree本身是一种类型,是一个指针,是指向结果体指针的类型*/ //这算是问题一
//问题二是:关于栈的各种各样的操作,进栈,进的应该是指向树根的指针
//问题三是:为什么要定义一个指向指针的指针
char ch;
*T=(BinTree)malloc(sizeof(BinTnode));
if(!*T) printf("overflow");
do{
ch=getchar();
if(ch==' ')
{ *T=NULL;
return 0;
}
else{
(*T)->data=ch;
CreateBinTree(&((*T)->lchild));
CreateBinTree(&((*T)->rchild));
return 1;
}
}while(ch!='\0');
}
/*中序递归遍历*/
void InorderTransverse(BinTree s)
{
if (s)
{
InorderTransverse(s->lchild);
printf("%c", s->data);
InorderTransverse(s->rchild);
}
}
//先序递归遍历二叉树
void PreOrderTranverseTree(BinTree s){
if (s)
{
printf("%c", s->data);
PreOrderTranverseTree(s->lchild);
PreOrderTranverseTree(s->rchild);
}
}
//后序递归遍历二叉树
void PostOrderTranverseTree(BinTree s){
if (s)
{
PreOrderTranverseTree(s->lchild);
PreOrderTranverseTree(s->rchild);
printf("%c", s->data);
}
}
/*主方法*/
void main(){
BinTree T;
printf("请按照先序的顺序输入要创建的树:\n");
CreateBinTree(&T); /*中序序列创建二叉树*/
printf("中序递归遍历的序列是:");
InorderTransverse(T);
printf("\n");
//先序递归遍历
printf("先序递归遍历的序列是:");
PreOrderTranverseTree(T);
printf("\n");
//后序递归遍历
printf("后序递归遍历的序列是:");
PostOrderTranverseTree(T);
printf("\n");