实验四 二叉树的操作

实验性质:综合性实验

要求:

(1) 采用二叉链表结构建立二叉树;
(2) 编程实现二叉树的先序、中序、后序和层序遍历;
(3) 编程实现非递归中序遍历
(3) 编程实现:求二叉树的高度和叶子结点个数;

目的:

(1)掌握二叉树的二叉链表存储方式及二叉树的特征;
(2)验证二叉树在二叉链表存储结构下遍历操作的实现;

示例

  • 创建
    输入 :ABC##DE#G##F###
    该输入对应的树如图所示
    在这里插入图片描述

  • 先序 屏幕输出 A B C D E G F

  • 后序 屏幕输出 C G E F D B A

  • 中序 屏幕输出 C B E G D F A

  • (中序非递归还需看源代码)

  • 层序 屏幕输出 A B C D E F G

  • 深度 屏幕显示 深度为5

代码

#include <iostream>
#define QElemType BiTree
#define SElemType BiTree
#define MAXSIZE 30
using namespace std;

typedef char TElemType;

//定义二叉链表存储结构
typedef struct BiTNode
{
    TElemType data;  //数据域
    struct BiTNode *lchild,*rchild;  //指针域
}BiTNode,*BiTree;
//循环队列类型定义
typedef struct
{
    QElemType *base;
    int front;
    int rear;
}SqQueue;
//顺序栈定义
typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;
//二叉树
void InitBiTree(BiTree &T);    //构造空二叉树
void CreateBiTree(BiTree &T);//先序遍历建立二叉链表
void PreOrderTraverse(BiTree T); //先序遍历
void InOrderTraverse(BiTree T); //中序遍历
void PostOrderTraverse(BiTree T);   //后序遍历
void LevelOrderTraverse(BiTree T);  //层序遍历
void InOrderTraverse2(BiTree T);    //非递归中序遍历
int Depth(BiTree T); //计算二叉树深度
int LeafCount(BiTree bt);  //计算叶子节点个数

//顺序栈
bool InitStack(SqStack &S); //顺序栈的初始化
bool Push(SqStack &S,SElemType e);//顺序栈的入栈
bool Pop(SqStack &S,SElemType e); //删除栈顶元素
bool StackEmpty(SqStack S);
SElemType GetTop(SqStack S); //取栈顶元素

//队列
bool InitQueue(SqQueue &Q);//初始化队列
bool EnQueue(SqQueue &Q,QElemType e);//元素入队
bool DeQueue(SqQueue &Q,QElemType &e);//元素出队
bool DestroyQueue(SqQueue &Q);//销毁队列
bool QueueEmpty(SqQueue Q);//队列判空

void Menu();  //文字菜单提示信息

int main()
{
    BiTree T;
    InitBiTree(T);
    Menu();
    int i;  //输入的数字
    cout<<"请输入操作代码:";
    cin>>i;
    while(true)
    {
        switch(i)
        {
        case 1:
            cout<<"输入字符序列,#代表空:";
            CreateBiTree(T);
            cout<<"创建成功"<<endl;
            break;
        case 2:
            cout<<"先序遍历结果为:";
            PreOrderTraverse(T);
            cout<<endl;
            break;
        case 3:
            cout<<"中序遍历结果为:";
            InOrderTraverse(T);
            cout<<endl;
            break;
        case 4:
            cout<<"后序遍历结果为:";
            PostOrderTraverse(T);
            cout<<endl;
            break;
        case 5:
            cout<<"层序遍历结果为:";
            LevelOrderTraverse(T);
            cout<<endl;
            break;
        case 6:
            cout<<"非递归中序遍历结果为:";
            InOrderTraverse2(T);
            cout<<endl;
            break;
        case 7:
            cout<<"二叉树深度为:"<<Depth(T)<<endl;
            break;
        case 8:
            cout<<"二叉树叶子结点个数为:"<<LeafCount(T)<<endl;
            break;
        default:
            if(i<0)
                return 0;
            else
            {
                cout<<"输入的位置非法,请重新输入";
                break;
            }
        }
        cout<<"请输入操作代码:";
        cin>>i;
    }
    return 0;
}
//二叉树
void InitBiTree(BiTree &T)
{
    T = new BiTNode;
    T->lchild = T->rchild = NULL;
    T->data = '#';
}
void CreateBiTree(BiTree &T) //先序遍历建立二叉链表
{
    char ch;
    cin>>ch;
    if(ch=='#')
        T=NULL;
    else
    {
        T=new BiTNode;
        T->data=ch;
        CreateBiTree(T->lchild);    //递归创建左子树
        CreateBiTree(T->rchild);    //递归创建右子树
    }
}
void PreOrderTraverse(BiTree T) //先序遍历
{
    if(T)
    {
        cout<<T->data;  //访问根节点
        PreOrderTraverse(T->lchild); //先序遍历左子树
        PreOrderTraverse(T->rchild);
    }
}
void InOrderTraverse(BiTree T) //中序遍历
{
    if(T)
    {
        InOrderTraverse(T->lchild); //中序遍历左子树
        cout<<T->data;  //访问根节点
        InOrderTraverse(T->rchild);
    }
}
void PostOrderTraverse(BiTree T)   //后序遍历
{
    if(T)
    {
        PostOrderTraverse(T->lchild); //后序遍历左子树
        PostOrderTraverse(T->rchild);
        cout<<T->data;  //访问根节点
    }
}
void LevelOrderTraverse(BiTree T)  //层序遍历
{
     //将每一层的节点分别入队列,然后分别读取,读取后继续将它们的子节点入队,所以保证是按照一层一层来遍历的
    BiTree P=T;
    SqQueue Q;
    InitQueue(Q);   //初始化队列
    if(P)
    {
        EnQueue(Q,P);
        while(!QueueEmpty(Q))
        {
            DeQueue(Q,P);   //出队列
            cout<<P->data;
            if(P->lchild)
                EnQueue(Q,P->lchild);
            if(P->rchild)
                EnQueue(Q,P->rchild);
        }
    }
    DestroyQueue(Q);
}
void InOrderTraverse2(BiTree T)    //非递归中序遍历
{
    SqStack S;InitStack(S);
    BiTree p=T;BiTree q=new BiTNode;
    while(p||!StackEmpty(S))
    {
        if(p)
        {
            Push(S,p);
            p=p->lchild;
        }
        else
        {
            q=GetTop(S);
            Pop(S,q);
            cout<<q->data;
            p=q->rchild;
        }
    }
}
int Depth(BiTree T)
{
    if(T==NULL) return 0;
    else
    {
        int m=Depth(T->lchild);
        int n=Depth(T->rchild);
        if(m>n)
            return(m+1);
        else
            return(n+1);
    }
}
int LeafCount(BiTree T)
{
    if(!T)          //结点为空
        return 0;
    if(!T->lchild&&!T->rchild)      //没有子节点了
        return 1;
    else
        return LeafCount(T->lchild)+LeafCount(T->rchild);
}

//顺序栈
bool InitStack(SqStack &S) //顺序栈的初始化
{
    S.base=new SElemType[MAXSIZE];
    if(!S.base)
        return 0;
    else
    {
        S.top=S.base;   //top初始化为base,空栈
        S.stacksize=MAXSIZE;
        return 1;
    }
}
bool Push(SqStack &S,SElemType e)//顺序栈的入栈
{
    if(S.top-S.base==S.stacksize)
        return 0;
    else
    {
        *S.top++=e;
        return 1;
    }
}
bool Pop(SqStack &S,SElemType e) //删除栈顶元素
{
    if(S.top==S.base)
        return 0;
    e=*--S.top;
    return 1;

}
bool StackEmpty(SqStack S)
{
    if(S.top==S.base)
        return true;
    else
        return false;
}
SElemType GetTop(SqStack S)
{
    if(S.top!=S.base)
        return *(S.top-1);
}

//队列
bool InitQueue(SqQueue &Q)//构造一个空队列
{
    Q.base=new QElemType[MAXSIZE];
    if(!Q.base)
        return 0;
    Q.front=Q.rear=0;
    return 1;
}
bool EnQueue(SqQueue &Q,QElemType e)//元素入队
{
    if((Q.rear+1)%MAXSIZE==Q.front)
        return 0;
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXSIZE;
    return 1;
}
bool DeQueue(SqQueue &Q,QElemType &e)//元素出队
{
    if(Q.front==Q.rear)
        return 0;
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXSIZE;
    return 1;
}
bool QueueEmpty(SqQueue Q)//判断队列是否为空
{
    if(Q.rear==Q.front)
        return 1;
    else
        return 0;
}
bool DestroyQueue(SqQueue &Q)//销毁队列
{
    if(!Q.base)
        return 0;
    Q.rear=Q.front;
    delete Q.base;
    return 1;
}

void Menu()
{
    cout << "---------------------------" << endl;
    cout << "****by 夏日****" << endl;
    cout << "---------------------------" << endl;
    cout << "1-----创建二叉链表 "<< endl;
    cout << "2-----先序遍历" << endl;
    cout << "3-----中序遍历" << endl;
    cout << "4-----后序遍历" << endl;
    cout << "5-----层序遍历" << endl;
    cout << "6-----非递归中序遍历" << endl;
    cout << "7-----二叉树深度" << endl;
    cout << "8-----二叉树叶子结点个数" << endl;
    cout << "   退出,输入一个负数!" << endl;
}

输出示例

在这里插入图片描述

写在最后

本文章仅供个人复习使用,如有错误,请联系我更正。

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值