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

实验项目五 二叉树基本操作的实现

课程名称:数据结构

实验项目名称:二叉树基本操作的实现

实验目的:

  • 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 << "先序遍历:\n";
            DgXx(T);
            cout << endl;
            cout << "中序遍历:\n";
            DgZx(T);
            cout << endl;
            cout << "后序遍历:\n";
            DgHx(T);
            cout << endl;
        }
        else if(temp == 1){
            cout << "先序遍历:\n";
            InRrderTraverse0(T);
            cout << endl;
            cout << "中序遍历:\n";
            InRrderTraverse1(T);
            cout << endl;
            cout << "后序遍历:\n";
            InRrderTraverse2(T);
            cout << endl;
        }
        else    break;
        printf("请输入遍历二叉树的方法,0:递归遍历,1:递归遍历,其他数字:结束询问\n");
    }
        printf("感谢使用\n");
    return 0;
}
  • 19
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值