输入FCA##DB###EH##GM###创建二叉树
思路:非递归无非就是把递归的栈实现过程自己写出来,要想理解非递归,首先要理解二叉树递归遍历的栈具体实现过程,建议大家可以通过DeBug查看递归执行的过程
#include <stdio.h>
#include <malloc.h>
//FCA##DB###EH##GM###
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int i=0;
BiTree CreateBiTree(){
BiTree T;
char c;
scanf("%c",&c);
if('#'==c){
T = NULL;
} else{
T=(BiTree)malloc(sizeof(BiTNode));
T->data = c;
T->lchild = CreateBiTree();//递归(栈)递推,回溯
T->rchild = CreateBiTree();
}
return T;
}
int top = -1;
//进栈函数
void push(BiTree* a,BiTree elem){
a[++top]=elem;
}
//弹栈函数
void pop( ){
if (top==-1) {
return ;
}
top--;
}
//模拟操作结点元素的函数,输出结点本身的数值
void displayElem(BiTree elem){
printf("%c\n",elem->data);
}
//拿到栈顶元素
BiTree getTop(BiTree* a){
return a[top];
}
//先序遍历非递归算法
void Pre(BiTree Tree){
BiTree a[20];
BiTree p;
push(a, Tree);//根结点进栈
while (top!=-1) {
p=getTop(a);//取栈顶元素
pop();//弹栈
while (p) {
displayElem(p);//调用结点的操作函数
//如果该结点有右孩子,右孩子进栈
if (p->rchild) {
push(a,p->rchild);
}
p=p->lchild;//一直指向根结点最后一个左孩子
}
}
}
//中序遍历非递归算法
void In(BiTree Tree){
BiTree a[20];
BiTree p;
push(a, Tree);//根结点进栈
while (top!=-1) {
while ((p=getTop(a)) &&p){//取栈顶元素,且不能为NULL
push(a, p->lchild);//将该结点的左孩子进栈,如果没有左孩子,NULL进栈
}
pop();//跳出循环,栈顶元素肯定为NULL,将NULL弹栈
if (top!=-1) {
p=getTop(a);//取栈顶元素
pop();//栈顶元素弹栈
displayElem(p);
push(a, p->rchild);//将p指向的结点的右孩子进栈
}
}
}
//后序遍历非递归算法
typedef struct SNode{
BiTree p;
int tag;
}SNode;
//后序遍历使用的进栈函数
void postpush(SNode *a,SNode sdata){
a[++top]=sdata;
}
//后序遍历函数
void Post(BiTree Tree){
SNode a[20];//定义一个顺序栈
BiTNode * p;//临时指针
int tag;
SNode sdata;
p=Tree;
while (p||top!=-1) {
while (p) {
//为该结点入栈做准备
sdata.p=p;
sdata.tag=0;//由于遍历是左孩子,设置标志位为0
postpush(a, sdata);//压栈
p=p->lchild;//以该结点为根结点,遍历左孩子
}
sdata=a[top];//取栈顶元素
pop();//栈顶元素弹栈
p=sdata.p;
tag=sdata.tag;
//如果tag==0,说明该结点还没有遍历它的右孩子
if (tag==0) {
sdata.p=p;
sdata.tag=1;
postpush(a, sdata);//更改该结点的标志位,重新压栈
p=p->rchild;//以该结点的右孩子为根结点,重复循环
}
//如果取出来的栈顶元素的tag==1,说明此结点左右子树都遍历完了,可以调用操作函数了
else{
displayElem(p);
p=NULL;
}
}
}
int main()
{
BiTree T;
T = CreateBiTree();
printf("先序遍历结果:\n");
Pre(T);
printf("中序遍历结果:\n");
In(T);
printf("后序遍历结果:\n");
Post(T);
return 0;
}