二叉排序树的创建、插入、删除和查询(给出查找成功和不成功时的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]++;
}
if ((parent.front()->lchild != NULL&&parent.front()->rchild == NULL) && p == parent.front()->lchild)
{
for (int j = 0; j < fu[i]; j++)
parent.pop();
i++;
}
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++;
}
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;
}
}