#include<iostream>
using namespace std;
struct BSTree
{
int key;
BSTree *lchild,*rchild;
};
BSTree* SearchBST1(BSTree *t,int k)//二叉排序树的查找递归算法
{
if(!t||k==t->key) return t;
else
{
if(k<t->key) return SearchBST1(t->lchild,k);//查找左孩子
else
return SearchBST1(t->rchild,k);//查找右孩子
}
}
BSTree* SearchBST2(BSTree *t,int k)//二叉排序树的查找非递归算法
{
BSTree *p = t;
while(p!=NULL&&p->key!=k)
{
if(k<p->key) p=p->lchild;
else p=p->rchild;
}
return p;
}
//插入一个关键字k与建立一棵二叉排序树算法是一样的
BSTree * InsertBST2(BSTree *t,int k)//插入关键字k,非递归
{
//若二叉排序树 t 中没有关键字k,则插入,否则直接返回
BSTree *p=t;//p的初值指向根结点
BSTree *f;//f保存当前查找的结点
while(p)//查找插入位置,插入位置一定是一个叶子结点
{
if(p->key==k)//树中已有k,无需插入
{
cout<<"树中存在"<<k<<",插入失败"<<endl;
return t;
}
f=p;
//若k<p->key,在左子树上查找,否则在右子树上查找
p=(k<p->key)?p->lchild:p->rchild;
}
p = new BSTree;
p->key=k;
p->lchild=p->rchild=NULL;
if(t==NULL)t=p;//插入结点为新的根结点
else if(k<f->key)f->lchild = p;//插入结点为左孩子
else f->rchild = p;//插入结点为右孩子
return t;
}
BSTree * InsertBST1(BSTree *t,BSTree *p,BSTree *f,int k)//插入关键字k,递归
{
//t二叉排序树的根,p待插入结点,初值为t, f表示p的父结点
if(t==NULL)
{
p = new BSTree;
p->key=k;
p->lchild=p->rchild=NULL;
t=p;//树为空,p为根
//cout<<"插入"<<k<<endl;
}
else
if(p!=NULL&&k==p->key)//树中已有k,无需插入
{
cout<<"树中存在"<<k<<",插入失败"<<endl;
return t;
}
else
if(p==NULL)//找到插入位置
{
p = new BSTree;
p->key=k;
p->lchild=p->rchild=NULL;
if(k<f->key)f->lchild = p;//插入结点为左孩子
else f->rchild = p;//插入结点为右孩子
//cout<<"插入"<<k<<endl;
}
else
{
if(k<p->key)
{
//cout<<"左"<<endl;
f=p;//f保存p的父结点
InsertBST1(t,p->lchild,f,k);//查找左孩子
}
else
{
//cout<<"右"<<endl;
f=p;
InsertBST1(t,p->rchild,f,k);//查找右孩子
}
}
return t;
}
void DelBST(BSTree *t,int k)//删除关键字k
{
BSTree *p=t;//p的初值指向根结点
BSTree *f = NULL;
BSTree *r,*s;//*s是被删结点的*p的直接前驱(中序遍历的前驱),*r是*s的双亲
while(p)
{
if(p->key==k)break;//找到关键字为k的结点
f=p;
p=(k<p->key)?p->lchild:p->rchild;
}
if(!p)return;//二叉排序树中无关键字为k的结点
if(p->lchild==NULL&&p->rchild==NULL)//*p是叶子
{
if(p==t)t=NULL;//*p既是叶子,又是根
else if(p==f->lchild)f->lchild=NULL;
else f->rchild=NULL;
free(p);
}
else
if(p->lchild==NULL && p->rchild!=NULL) // *p只有右子树
{
if(f->lchild==p)
f->lchild=p->rchild;//将*p的右子树链接到其父结点的左链上
else
f->rchild=p->rchild;//将*p的右子树链接到其父结点的右链上
free(p);
}
else if(p->rchild==NULL&&p->lchild!=NULL)//*p只有有左子树
{
if (f->lchild==p)
f->lchild=p->lchild; //将*p的左子树链接到其父结点的左链上
else
f->rchild=p->lchild; //将*p的左子树链接到其父结点的右链上
free(p);
}
else if(p->lchild!=NULL&&p->rchild!=NULL)//*p既有左子树,又有右子树
{
r=p;s=p->lchild;
while(s->rchild)//中序遍历*P的前驱*s,要么是叶子结点,要么没有右孩子
{
r=s;s=s->rchild;
}
p->key=s->key;//用*s替换*p
if(r!=p) r->rchild=s->lchild;//将*s的左子树链接到*r的右链上
else r->lchild = s->lchild;
free(s);
}
}
void Travel(BSTree *t)
{
if(t==NULL)return;
else
{
Travel(t->lchild);
cout<<t->key<<" ";
Travel(t->rchild);
}
}
void select()
{
cout<<"欢迎进入二叉树排序操作界面!!!"<<endl;
cout<<"1,初始化一棵二叉排序树"<<endl;
cout<<"2,在二叉排序树上查找一个元素"<<endl;
cout<<"3,在二叉排序树上插入一个元素"<<endl;
cout<<"4,在二叉排序树上删除一个元素"<<endl;
cout<<"5,中序遍历二叉排序树"<<endl;
cout<<"0,操作结束"<<endl;
}
int main()
{
BSTree *t=NULL;
BSTree *p,*f;
select();
int n;
int k;
int i;
while(1)
{
cout<<"请输入操作序号:"<<endl;
cin>>n;
switch(n)
{
case 0:exit(0);
case 1:cout<<"请输入二叉排序树的结点个数"<<endl;
cin>>n;
cout<<"输入结点的值"<<endl;
for(i=1;i<=n;i++)
{
cin>>k;
//t=InsertBST2(t,k);
t=InsertBST1(t,t,f,k);
}
cout<<"二叉排序树建立完成"<<endl;break;
case 2:cout<<"请输入查找元素的值"<<endl;
cin>>k;
p = SearchBST1(t,k);
if(p==NULL)cout<<k<<"不存在."<<endl;
else cout<<k<<"存在."<<endl;break;
case 3:cout<<"请输入插入元素的值"<<endl;
cin>>k;
InsertBST2(t,k);
cout<<"插入操作完成"<<endl;
break;
case 4:cout<<"请输入删除元素的值"<<endl;
cin>>k;
DelBST(t,k);
cout<<"删除元素成功"<<endl;break;
case 5:cout<<"中序遍历二叉树为:"<<endl;
Travel(t);cout<<endl;break;
}
}
return 0;
}
二叉排序树
最新推荐文章于 2021-11-26 19:25:12 发布