数据结构——二叉树的递归与非递归遍历(先序,中序,后序)

实验项目五 二叉树基本操作的实现
课程名称:数据结构
实验项目名称:二叉树基本操作的实现
实验目的:
1.掌握树的基本操作—遍历。
实验要求:
1、 分别用递归和非递归的方法实现一棵树的三种遍历。
实验过程:
1、 创建一棵二叉树(二叉树如下图所示);
2、 用递归算法实现对该树的三种遍历;
3、 用非递归算法实现对该树的三种遍历;
4、 输入选项:0或1,0为递归遍历,1为非递归遍历。
5、 根据输入的选项,分别调用递归或非递归算法输出先序、中序、后序遍历序列。
实验报告中给出先序和后序遍历的非递归实现算法代码。
实验结果:
1、输入:ABD##E##CF#G###(创建二叉树)
2、输入:0(递归算法)
3、输出:先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA
4、输入:1(非递归实现)
5、输出:先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA

#include<bits/stdc++.h>
using namespace std;
#define TElemType char
typedef int Status;
#define OK 1
#define ERROR 0
char ch;
const int MAXSIZE=110;

typedef struct BiTNode {
    TElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode ,*BiTree;

BiTNode *T;
BiTree q,p;

typedef BiTree SElemType;

typedef struct{//定义顺序栈
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;
SqStack S;
Status InitStack(SqStack &S){
    S.base=new SElemType[MAXSIZE];
    if(!S.base) exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}
Status Push(SqStack &S,SElemType e)//入栈
{
    if(S.top-S.base==S.stacksize)  //判断栈满
        return ERROR;
    *S.top++=e;                     //元素e压入栈顶,栈顶指针上移一位;
    return OK;
 }
Status Pop(SqStack &S,SElemType &e){//出栈
    if(S.top==S.base)   return ERROR;
    e=*--S.top;
    return OK;
}
SElemType GetTop(SqStack S){//取栈顶元素
    if(S.top!=S.base)   return *(S.top-1);
}
Status StackEmpty(SqStack &S){
    if(S.top-S.base ==0)    return OK;
    else return ERROR;
}

void CreatBiTree(BiTree &T){//建树
    cin>>ch;//读入字符
    if(ch=='#')T=NULL;//如果字符为'#',说明已经到了叶结点
    else{//递归
        T=new BiTNode;
        T->data = ch;
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);
    }
}
void DgXx(BiTree T){//递归先序
    if(T){
        cout<<T->data;
        DgXx(T->lchild);
        DgXx(T->rchild);
    }
}
void DgZx(BiTree T){//递归中序
    if(T){
        DgZx(T->lchild);
        cout<<T->data;
        DgZx(T->rchild);
    }
}
void DgHx(BiTree T){//递归后序
    if(T){
        DgHx(T->lchild);
        DgHx(T->rchild);
        cout<<T->data;
    }
}
void InRrderTraverse0(BiTree T){//非递归先序
    InitStack(S);//初始化栈S
    p = T;
    while(p||!StackEmpty(S)) {//如果树不为空或者栈不为空
        if(p){
            Push(S,p) ;//将结点入栈
            cout<<p->data;//输出根结点的值
            p = p->lchild ;//把左孩子作为根节点
        }
        else{//如果树空,说明左树已经遍历完成
            Pop(S, p) ;//弹出结点
            p = p->rchild ;//开始遍历右树
        }
    }
}
void InRrderTraverse1(BiTree T){//非递归中序遍历
    InitStack(S);//初始化栈
    p = T;
    q = new BiTNode;
    while(p||!StackEmpty(S)){
        if(p){//p非空
            Push(S,p);//根指针进栈
            p=p->lchild;//根指针进栈,遍历左子树
        }
        else{//p为空
            Pop(S,q);//退栈
            cout<<q->data;//访问根结点
            p=q->rchild;//遍历右子树
        }
    }
}
void InRrderTraverse2(BiTree T){//非递归后序遍历
    InitStack(S);
    Push(S,T);//把根节点进栈
    BiTNode *pre ,*cur;
    cur=NULL;//当前结点
    pre=NULL;//上一结点
    while(!StackEmpty(S)){//栈非空
        cur=GetTop(S);//把根节点给当前结点
        if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild ||pre == cur->rchild)))
        {//如果左右子树都没有或者左右子树都已经访问过了
            cout<<cur->data;//直接输出根结点
            Pop(S,cur);//将此时的根节点弹出
            pre=cur;//更新pre
        }
        else{//记得先进右子树后进左子树,这样输出的顺序才对。
            if(cur->rchild != NULL){//如果右子树不为空
                Push(S,cur->rchild) ;//把右子树进栈
            }
            if(cur->lchild != NULL){//如果左子树不为空
                Push(S,cur->lchild) ;//把左子树进栈
            }
        }
    }
}
int main(){
    CreatBiTree(T);
    int temp;
    printf("请输入遍历二叉树的方法,0:递归遍历,1:递归遍历,其他数字:结束询问\n");
    while(scanf("%d",&temp)!=EOF){
        if(temp==0){
            cout<<"先序遍历:";
            cout<<endl;
            DgXx(T);
            cout<<endl;
            cout<<"中序遍历:";
            cout<<endl;
            DgZx(T);
            cout<<endl;
            cout<<"后序遍历:";
            cout<<endl;
            DgHx(T);
            cout<<endl;
        }
        else if(temp==1){
            cout<<"先序遍历:";
            cout<<endl;
            InRrderTraverse0(T);
            cout<<endl;
            cout<<"中序遍历:";
            cout<<endl;
            InRrderTraverse1(T);
            cout<<endl;
            cout<<"后序遍历:";
            cout<<endl;
            InRrderTraverse2(T);
            cout<<endl;
        }
        else{
            break;
        }
        printf("请输入遍历二叉树的方法,0:递归遍历,1:递归遍历,其他数字:结束询问\n");
    }
        printf("感谢使用\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/l18339702017/article/details/78836862