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

来源:互联网 发布:单片机智能反编译器 编辑:程序博客网 时间:2024/05/18 21:41

实验项目五 二叉树基本操作的实现
课程名称:数据结构
实验项目名称:二叉树基本操作的实现
实验目的:
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 chartypedef int Status;#define OK 1#define ERROR 0char 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;}
阅读全文
1 0
原创粉丝点击