二叉排序树

来源:互联网 发布:学编程怎么开始学 编辑:程序博客网 时间:2024/05/29 15:13

特点:

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;}



0 0