一、设计思想递归实现二叉树遍历的思想: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 <stdlib.h>/*定义二叉树*/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");用非递归的方式实现二叉树的遍历#include "stdio.h"#include "conio.h"#include <stdlib.h>/*定义二叉树*/typedef struct node{char data;struct node *lchild, *rchild;}BinTnode;typedef BinTnode * BinTree; //定义二叉树类型的指针/*栈的相关操作*/typedef struct{BinTree data[100];int top;}SeqStack;/*初始化栈*/void initStack(SeqStack *S){S->top =-1;}/*进栈*/void Push(SeqStack *S,BinTree x){ /*无论是进栈还是取栈顶元素都应该是指向树的指针*/if(S->top==100-1){printf("the stack is overflow");}else {S->top=S->top+1;S->data[S->top]=x;}}/*出栈*/int Pop(SeqStack *S,BinTree *p){if(S->top==-1){printf("the stack is underflow");return 0;}else {*p=S->data[S->top];--S->top;return 1;}}/*判断栈是不是空*/int EmptyStack(SeqStack S){if(S.top==-1) return 1;else return 0; /* 栈不空的情况*/}/*取出栈顶元素*/int GetTop(SeqStack S,BinTree *p){ //如果栈顶元素取到的是一颗子树的话,那应该返回的是。
,栈顶取到的到底应该是什么哈if(S.top==-1){printf("the stack is empty");return 0;}else {*p=S.data[S.top];return 1;}//访问结点char visit(BinTree p){return (*p).data;}/*创建二叉树*/int CreateBinTree(BinTree *T){ /*BinTree本身是一种类型,是一个指针,是指向结果体指针的类型*/ //这算是问题一//问题二是:关于栈的各种各样的操作,进栈,进的应该是指向树根的指针//问题三是:为什么要定义一个指向指针的指针char ch;*T=(BinTree)malloc(sizeof(BinTnode));if(!*T) printf("overflow");else{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 T){SeqStack S;BinTree p;initStack(&S);//初始化栈printf("中序非递归序列是:");Push(&S,T); //根指针进栈T为指向二叉树的指针while(!EmptyStack(S)){ //栈不是空的情况while(GetTop(S,&p) && p)Push(&S,p->lchild); //gettop得到的结果也必须是一棵子树才行,进栈应该进的是树根的指针Pop(&S,&p);if(!EmptyStack(S)){//printf("%c",visit(p));Pop(&S,&p);printf("%c",visit(p));Push(&S,p->rchild);}}}/*先序非递归遍历*/void PreorderTransverse(BinTree T){SeqStack S;BinTree p;initStack(&S);//初始化栈Push(&S,T); //根指针进栈T为指向二叉树的指针printf("先序非递归序列是:");while(!EmptyStack(S)){Pop(&S,&p); //根节点出栈if(p!=NULL){printf("%c",visit(p));Push(&S,p->rchild);Push(&S,p->lchild);}}}/*后序非递归遍历*/void PostorderTransverse(BinTree T){SeqStack S;BinTree p,q;initStack(&S);//初始化栈p=T;printf("后序非递归序列是:");while(p ||!EmptyStack(S)){ //跳出while循环的原因是因为左子树或者右子树为空了if(p!=q){while(p!=NULL){Push(&S,p);if(p->lchild!=NULL)p=p->lchild;elsep=p->rchild;}}if(EmptyStack(S)) break;GetTop(S,&q);if(q->rchild==p){ //进栈的是右子树Pop(&S,&p);printf("%c",visit(p));p=q;}else{p=q->rchild;}}}/*主方法*/void main(){BinTree T;printf("请按照先序的顺序输入创建的树:\n");/*创建树*/CreateBinTree(&T);//中序非递归遍历InorderTransverse(T);printf("\n");//先序非递归遍历PreorderTransverse(T);printf("\n");//后序非递归遍历PostorderTransverse(T);}四、运行结果非递归方法遍历二叉树的运行结果如图5图5非递归方法遍历二叉树的结果图递归方法遍历二叉树的结果图如图6图6递归遍历二叉树的结果图五、遇到的问题及解决•首先遇到的问题是指针的问题以及指向指针的问题。