SCAU8608 实现二叉排序树的各种算法

数据结构综合性实验

用函数实现如下二叉排序树算法: 
(1) 插入新结点 
(2) 前序、中序、后序遍历二叉树 
(3) 中序遍历的非递归算法 
(4) 层次遍历二叉树 
(5) 在二叉树中查找给定关键字(函数返回值为成功1,失败0) 
(6) 交换各结点的左右子树 
(7) 求二叉树的深度 
(8) 叶子结点数

实现代码:

#include <cstdio>
#include <iostream>

using namespace std;

#define MAXSIZE 1000

typedef struct BiTNode //二叉树节点结构体
{
    int data;
    struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

typedef struct //栈
{
    BiTNode *base;
    BiTNode *top;
} Stack;

typedef struct //队列
{
    BiTNode *base;
    int qfront;
    int qrear;
} SqQueue;

void BiTreeInsert(BiTree &T,int dot)
{
    if(T==NULL) //此时树为空
    {
        T=new BiTNode; //卧槽了老是忘记新建空间
        //T=(BiTNode *)malloc(sizeof(BiTNode));
        T->data=dot;
        T->lchild=NULL;
        T->rchild=NULL;
    }
    else if(T->data>dot)
        BiTreeInsert(T->lchild,dot);
    else BiTreeInsert(T->rchild,dot);
}

void PreTraverse(BiTree &T) //先序遍历
{
    if(T)
    {
        cout<<T->data<<" ";
        PreTraverse(T->lchild);
        PreTraverse(T->rchild);
    }
}
void MidTraverse(BiTree &T) //中序遍历
{
    if(T)
    {
        MidTraverse(T->lchild);
        cout<<T->data<<" ";
        MidTraverse(T->rchild);
    }
}
void BackTraverse(BiTree &T) //后序遍历
{
    if(T)
    {
        BackTraverse(T->lchild);
        BackTraverse(T->rchild);
        cout<<T->data<<" ";
    }
}

void CreateBiTree(BiTree &T) //构建二叉树
{
    //由于题目没有给出叶节点符号
    //无法使用左右节点递归构建
    //使用插入法构建
    int n,dot;
    cin>>n;
    while(n--)
    {
        cin>>dot;
        BiTreeInsert(T,dot);
    }
}

void FindBiTree(BiTree &T,int dot) //查找关键字
{
    if(dot!=T->data)
    {
        if(T->data>dot)
        {
            if(T->lchild==NULL)
            {
                cout<<"0";
                return ;
            }
            else FindBiTree(T->lchild,dot);
        }
        else if(T->data<dot)
        {
            if(T->rchild==NULL)
            {
                cout<<"0";
                return ;
            }
            else FindBiTree(T->rchild,dot);
        }

    }
    else
    {
        cout<<"1";
        return;
    }
}

void CreateStack(Stack &S) //创造一个栈
{
    S.base=new BiTNode[MAXSIZE];
    S.top=S.base;
}
bool StackEmpty(Stack &S) //判断是否为空栈
{
    if(S.base==S.top)
        return true;
    return false;
}
void StackPush(Stack &S,BiTNode e) //入栈
{
    //这里不许要改e所以不用&
    *S.top=e;
    S.top++;
}
void StackPop(Stack &S,BiTNode &e) //出栈
{
    S.top--;
    e=*S.top;
}
void Other_PreTravserse(BiTree &T) //非递归中序遍历
{
    // 对于一个节点,如果有左孩子的话,左孩子入栈
    // 如果左孩子已经被遍历过了(或没有左孩子),直接输出该节点,该节点右孩子入栈
    Stack S;
    CreateStack(S);
    BiTNode *p=T;
    BiTNode *q=new BiTNode; //用来存pop出来的上一个节点
    while(p||!StackEmpty(S))
    {
        if(p)
        {
            StackPush(S,*p);
            p=p->lchild;
        }
        else
        {
            StackPop(S,*q);
            cout<<q->data<<" ";
            p=q->rchild;
        }
    }
}
void CreateQueue(SqQueue &Q)
{
    Q.base=new BiTNode[MAXSIZE];
    Q.qfront=Q.qrear=0;
}
bool EmptyQueue(SqQueue &Q)
{
    if(Q.qfront==Q.qrear) return true;
    else return false;
}
void PushQueue(SqQueue &Q,BiTNode e) //入队(有点难记一下)
{
    Q.base[Q.qrear]=e;
    //在地址为基地址+Q.qrear的空间放入指针
    Q.qrear++;
}
void PopQueue(SqQueue &Q,BiTNode &e)
{
    e=Q.base[Q.qfront];
    Q.qfront++;
}
void LayerTraverse(BiTree &T)
{
    SqQueue Q;
    CreateQueue(Q);
    BiTNode *p=T;
    BiTNode *q=new BiTNode; // 最开始没设置这个,卡了好久,每个点都直接在头结点上覆盖了
    PushQueue(Q,*p);
    while(!EmptyQueue(Q))
    {
        PopQueue(Q,*q);
        cout<<q->data<<" ";
        if(q->lchild)
            PushQueue(Q,*(q->lchild));
        if(q->rchild)
            PushQueue(Q,*(q->rchild));
    }
}

void SwapBiTree(BiTree &T)
{
    if(T)
    {
        BiTNode *temp;
        temp=T->lchild;
        T->lchild=T->rchild;
        T->rchild=temp;
        SwapBiTree(T->lchild);
        SwapBiTree(T->rchild);
    }
}

int Depth(BiTree &T)
{
    if(!T)
        return 0;
    int m=Depth(T->lchild);
    int n=Depth(T->rchild);
    if(m>n)return m+1;
    else return n+1;
}

int LeaveCount(BiTree &T)
{
    if(T==NULL)
        return 0;
    else if(!T->lchild&&!T->rchild)
        return 1;
    else return LeaveCount(T->lchild)+LeaveCount(T->rchild);
}

int main() //主函数
{
    BiTree T=NULL; //创建一个指向树的头指针
    //最开始一直卡输出……没想到是因为没写=NULL……吃大亏……
    CreateBiTree(T); //建树

    PreTraverse(T); //先序遍历并输出
    cout<<endl;
    MidTraverse(T); //中序遍历并输出
    cout<<endl;
    BackTraverse(T); //后序遍历并输出
    cout<<endl;

    int find1,find2;
    cin>>find1;
    FindBiTree(T,find1);// 查找关键字
    cout<<endl;
    cin>>find2;
    FindBiTree(T,find2);// 查找关键字
    cout<<endl;

    int key;
    cin>>key;
    BiTreeInsert(T,key); //插入关键字
    PreTraverse(T); //先序遍历并输出
    cout<<endl;
    MidTraverse(T); //中序遍历并输出
    cout<<endl;
    BackTraverse(T); //后序遍历并输出
    cout<<endl;

    Other_PreTravserse(T); //非递归中序遍历
    cout<<endl;
    LayerTraverse(T); //层序遍历
    cout<<endl;

    SwapBiTree(T); //交换左右子树
    PreTraverse(T); //先序遍历并输出
    cout<<endl;
    MidTraverse(T); //中序遍历并输出
    cout<<endl;
    BackTraverse(T); //后序遍历并输出
    cout<<endl;

    SwapBiTree(T); //交换左右子树
    PreTraverse(T); //先序遍历并输出
    cout<<endl;
    MidTraverse(T); //中序遍历并输出
    cout<<endl;
    BackTraverse(T); //后序遍历并输出
    cout<<endl;

    cout<<Depth(T)<<endl; //深度
    cout<<LeaveCount(T)<<endl; //叶子节点数

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值