二叉排序树的操作和ASL

二叉排序树的创建、插入、删除和查询(给出查找成功和不成功时的ASL)

#include <iostream>
#include <queue>
#include <stack>
using namespace std;
typedef struct BSTNode
{
    int data;
    struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;

void charu(BSTree &T,int e)
{

    BSTNode *S;
    if(!T)
    {
        S=new BSTNode;
        S->data=e;
        S->lchild=S->rchild=NULL;
        T=S;
    }
    else if(e<T->data)
        charu(T->lchild,e);
    else if(e>T->data)
        charu(T->rchild,e);
}

void chuangjian(BSTree &T)
{
    int e;
    T=NULL;
    cin>>e;
    while(e!=0)
    {
        charu(T,e);
        cin>>e;
    }
}

void zhongxvbianli(BSTree T)
{
    if(T)
    {
        zhongxvbianli(T->lchild);
        cout<<T->data<<' ';
        zhongxvbianli(T->rchild);
    }
}

void chazhao(BSTree T)
{   int key;
    BSTNode *p;
    cin>>key;
    p=T;
    while(p)
    {
        if(p->data==key) {cout<<"该数存在"<<endl;return;}
        if(p->data>key) p=p->lchild;
        else p=p->rchild;
    }
    if(!p) cout<<"该数不存在"<<endl;return;
}

void shanchu(BSTree &T)
{   int key;
    BSTNode *p,*f,*s,*q;
    cin>>key;
    p=T;f=NULL;
    while(p)
    {
        if(p->data==key) break;
        f=p;
        if(p->data>key) p=p->lchild;
        else p=p->rchild;
    }
    if(!p) return;
    q=p;
    if((p->lchild)&&(p->rchild))
    {
        s=p->lchild;
        while(s->rchild)
        {
            q=s;s=s->rchild;
        }
        p->data=s->data;
        if(q!=p) q->rchild=s->lchild;
        else q->lchild=s->lchild;
        delete s;
        return;
    }
    else if(!p->rchild)
    {
        p=p->lchild;
    }
    else if(!p->lchild)
    {
        p=p->rchild;
    }
    if(!f) T=p;
    else if(q==f->lchild) f->lchild=p;
    else f->rchild=p;
    delete q;
}

int ASL(BSTree T)
{
    queue<BSTree> a;
    queue<BSTree> parent;
    BSTree p;
    int n=0,w[10]={0},fu[10]={0},i=1,flag=1,r[10]={0};;
    if(T==NULL)return 0;
    a.push(T);
    while (!a.empty())
    {
        p=a.front();a.pop();
        if(p->rchild==NULL)
            r[i]++;
        if(p->lchild==NULL)
            r[i]++;
        w[i]++;   //每层元素个数
        n++;      //结点个数
        if(a.empty()&&flag==1)
            {
                i++;
                flag++;
                if (p->lchild == NULL&&p->rchild == NULL)break;
            }
        if(p->lchild!=NULL||p->rchild!=NULL)
            {
                if(p->lchild!=NULL)a.push(p->lchild);
                if(p->rchild!=NULL)a.push(p->rchild);
                parent.push(p);
                if (fu[1] == 0)
                    fu[1] = 1;//根节点
                else
                    fu[i]++; //父节点数量
            }
         //一层结束,父节点队列出队
         //左节点不为空,右节点为空,  且p等于左节点
         if ((parent.front()->lchild != NULL&&parent.front()->rchild == NULL) && p == parent.front()->lchild)
         {
             for (int j = 0; j < fu[i]; j++)
             parent.pop();
             i++;//一层结束
          }
         //右节点不为空,左节点为空,  且p等于右节点
         else if ((parent.front()->rchild != NULL&& parent.front()->lchild == NULL) && p == parent.front()->rchild)
         {
             for (int j = 0; j < fu[i]; j++)
             parent.pop();
             i++;//一层结束
          }
          //右节点不为空,左节点为空,  且p等于右节点
          else if (p == parent.front()->rchild)
          {
              for (int j = 0; j < fu[i]; j++)
              parent.pop();
              i++;//一层结束
          }
    }
    int s=0,z=0,t=0;
    for(int j=0;j<=i;j++)
    {
        s+=j*w[j];
        z+=j*r[j];
        t+=r[j];
    }
    printf("查找成功时的平均检索长度(ASL)=");
    cout<<s<<'/'<<n<<endl;
    printf("查找失败时的平均检索长度(ASL)=");
    cout<<z<<'/'<<t<<endl;

}

int main()
{
    BSTree T;
    cout<<"请输入要创建的二叉排序树(以0结束):\n";
    chuangjian(T);
    while(1)
    {
as:     cout<<"请选择要进行的操作:\n";
        cout<<"1.插入\n2.删除\n3.查询\n4.平均检索长度(ASL)\n5.结束\n";
        int e;cin>>e;
        system("cls");
        if(e==1)
        {
            cout<<"请输入要插入的数:\n";
            int t;cin>>t;charu(T,t);
            cout<<"操作成功!\n插入后的二叉排序树为:";zhongxvbianli(T);cout<<endl;
            cout<<"请选择要进行的操作:\n";
            cout<<"1.返回上一级\n2.结束\n";
            {
                int p;cin>>p;
                if(p==1){system("cls");goto as;}
                if(p==2)return 0;
            }
        }
        if(e==2)
        {
            cout<<"请输入要删除的数:\n";
            shanchu(T);cout<<"操作成功!\n删除后的二叉排序树为:";zhongxvbianli(T);cout<<endl;
            cout<<"请选择要进行的操作:\n";
            cout<<"1.返回上一级\n2.结束\n";
            {
                int p;cin>>p;
                if(p==1){system("cls");goto as;}
                if(p==2)return 0;
            }
        }
        if(e==3)
        {
            cout<<"请输入要查找的数:\n";
            chazhao(T);
            cout<<"请选择要进行的操作:\n";
            cout<<"1.返回上一级\n2.结束\n";
            {
                int p;cin>>p;
                if(p==1){system("cls");goto as;}
                if(p==2)return 0;
            }
        }
        if(e==4)
        {
            ASL(T);
            cout<<"请选择要进行的操作:\n";
            cout<<"1.返回上一级\n2.结束\n";
            {
                int p;cin>>p;
                if(p==1){system("cls");goto as;}
                if(p==2)return 0;
            }
        }
        if(e==5)
        return 0;
    }
}
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值