您的位置:首页 > 其它

二叉排序树

2015-12-13 21:17 381 查看
特点:

1)左子树非空则左子树所有节点的值小于根节点

2)右子树非空则右子树所有节点的值大于根节点

3)左右子树都为二叉排序树

查找次数等于树高,最坏情况为o(n),最好为o(log n)

以中序遍历输出则为有序序列,也可以称为树排序,排序复杂度o(n*log n)

# include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef int datatype;
struct bsnode
{
datatype data;
bsnode *l,*r;
bsnode(){l=r=NULL;}
};
bsnode* Insert(bsnode *t,datatype x)
{
bsnode *p=t,*f=NULL;//f为表示下一个点的父节点
while(p)
{
if(p->data==x) return t ; //若该值已在树中出现,就不必再插入
f=p;
if(x<p->data)  p=p->l; //比根小就往左边走
else p=p->r;//否则往右边
}
p=new bsnode();
p->data=x;
if(f==NULL) return p;
if(x<f->data)  f->l=p;
else f->r=p;
return t;
}
bsnode *create() //建立二叉排序树
{
datatype x;
bsnode *root=NULL;
cin>>x;
while(x!=-1)
{
root=Insert(root,x);
cin>>x;
}
return root;
}
void inorder(bsnode *t) //中序遍历输出
{
if(t==NULL) return ;
inorder(t->l);
cout<<t->data<<' ';
inorder(t->r);
}
bsnode * FindX(bsnode *t,datatype x) //递归查找值为x节点
{
if(t==NULL||t->data==x) return t;
if(x<t->data) return FindX(t->l,x);
return FindX(t->r,x);
}
void FindXbyloop(bsnode *t,bsnode **f,bsnode **p,datatype x) //非递归查找值x的节点和x父节点
{
*p=t;
*f=NULL;
while(*p)
{
if((*p) -> data==x)  return ;
*f=*p;
if(x<(*p)->data)  *p=(*p)->l;
else *p = (*p)->r;
}
}
bsnode *DeleteX(bsnode *t,datatype x) //二叉排序树删除节点
{
bsnode *p,*orderpre,*f,*q;
FindXbyloop(t,&f,&p,x);//找到待删除的节点和父亲
q=p;//保存待删点
if(p==NULL) return t;
if(p->l==NULL&&p->r==NULL) //删除的为叶子节点
{
if(f==NULL) t=NULL; //若只有根节点,返回空树
else if(f->l->data==x) f->l=NULL; // 若左儿子等于x,父节点左儿子指向为空
else f->r=NULL; //否则右儿子为空
free(q);
}
else if(p->l==NULL) //删除一度节点且删除节点左儿子为空
{
if(f==NULL) t=p->r; //若该节点为根,左儿子右儿子作为根
else if(f->l->data==x)  f->l=p->r; // 节点位于中间,父节点的左儿子为删除节点,使父节点左儿子指向删除节点的右儿子
else f->r=p->r; //父节点的右儿子指向删除节点的右儿子
free(q);
}
else if(p->r==NULL) //删除一度节点且右儿子为空
{
if(f==NULL)  t=p->l;
else if(f->l->data==x) f->l=p->l;
else f->r=p->l;
free(q);
}
else //删除二度节点(把删除节点右子树的前趋替换删除节点)
{
orderpre = p->r;
while(orderpre->l) orderpre=orderpre->l;//找到右子树的前趋
orderpre->l=p->l;//使得删除节点的左子树作为右子树前趋节点的左左子树
if(f==NULL)  t=p->r; //如果被删除的是根,被删除节点的右儿子作为根
else if(f->l->data==x) f->l=p->r; //节点处于中间,父节点的左儿子为删树节点,则把删除节点的右儿子作为父节点的左儿子
else f->r=p->r;
free(q);
}
return t;
}
int main()
{
datatype  x;
int n = 5;
bsnode *root,*p,*f;
root=create();
inorder(root);
cout<<endl;
/* cin>>x;
p=FindX(root,x);
if(p) cout<<p->data<<endl;
else cout<<"不存在"<<endl;*/
/*  FindXbyloop(root,&f,&p,x);
if(p!=NULL) cout<<f->data<<"   "<<p->data<<endl;*/
while(n)
{
cin>>x;
root=DeleteX(root,x);
inorder(root);
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: