zoukankan      html  css  js  c++  java
  • 二叉排序树:删除操作

    删除分为两种可能:
    1.只有左子树,或右子树,或叶结点。

    q=p;
    p=p->left;
    free(q);

    叶结点、只有右子树的情况相似。

    2.有左子树和右子树的情况

    先看完整代码:

    int Delete(Tree &p)
    {
        Tree q,s;
        if(p->right==NULL)/*只有左子树*/
        {
            q=p;
            p=p->left;
            free(q);
        }
        else if(p->left==NULL)/*只有右子树*/
        {
            q=p;
            p=p->right;
            free(q);
        }
        else
        {
            q=p;
            s=p->left;
            while(s->right)
            {
                q=s;
                s=s->right;
            }
            p->data=s->data;
            if(q!=p)
            {
                q->right=s->left;
            }
            else
            q->left=s->left;
            free(s);
        }
        return TRUE;
    }
    int DeleteBSF(Tree &T,int key)
    {
        if(!T)
        return FALSE;
        else
        {
            if(key==T->data)
            return Delete(T);
            else if(key<T->data)
            return DeleteBSF(T->left,key);
            else
            return DeleteBSF(T->right,key);
        }
    }
    View Code

    先将s移到待删节点的前驱,方法是:先左转,再一直右转。如图所示,s左转,然后接着右转,结果右转直接为空。此时的状态是:p=q; s=p->left。




    另一种情况,右树不为空,一直往前移动,这个时候的规律是:p总指向s的父结点。操作如下:

    q->left=s->left;
    free(s);

    删除的五种可能样式:
     

    /*------二叉排序树的查找、插入操作------*/
    
    #include <iostream>
    using namespace std;
    #define TRUE 1
    #define FALSE 0
    typedef struct node
    {
        int data;
        struct node *left,*right;
    }*Tree,Node;
    int Delete(Tree &p)
    {
        Tree q,s;
        if(p->right==NULL)/*只有左子树*/
        {
            q=p;
            p=p->left;
            free(q);
        }
        else if(p->left==NULL)/*只有右子树*/
        {
            q=p;
            p=p->right;
            free(q);
        }
        else
        {
            q=p;
            s=p->left;
            while(s->right)
            {
                q=s;
                s=s->right;
            }
            p->data=s->data;
            if(q!=p)
            {
                q->right=s->left;
            }
            else
            q->left=s->left;
            free(s);
        }
        return TRUE;
    }
    int DeleteBSF(Tree &T,int key)
    {
        if(!T)
        return FALSE;
        else
        {
            if(key==T->data)
            return Delete(T);
            else if(key<T->data)
            return DeleteBSF(T->left,key);
            else
            return DeleteBSF(T->right,key);
        }
    }
    int Search(Tree &T,int key,Tree f,Tree &p)/*查找*/
    {
        if(!T)/*最后一步依然没有找到等于key的数据*/
        {
            p=f;/*f必定是叶子结点*/
            return FALSE;
        }
        else if(key==T->data)
        {
            p=T;/*指向等于key的数据*/
            cout<<"f->data="<<f->data<<endl;
            return TRUE;
        }
        else if(key<T->data)
        {
            return Search(T->left,key,T,p);
        }
        else
            return Search(T->right,key,T,p);
    }
    int Insert(Tree &T,int key,Tree &p)/*插入*/
    {
        Tree s;
        if(!Search(T,key,NULL,p))/*如果没有key这个数据*/
        {
            s=(Tree)malloc(sizeof(Node));
            s->data=key;
            s->left=s->right=NULL;
            if(!p)/*如果是棵空树*/
            {
                T=s;/*s就为根结点*/
            }
            else if(key<p->data)
            {
                p->left=s;
            }
            else if(key>p->data)
            {
                p->right=s;
            }
            return TRUE;
        }
        return FALSE;
    }
    void Traverse(Tree &T)/*遍历*/
    {
        if(T)
        {
            Traverse(T->left);
            cout<<T->data<<" ";
            Traverse(T->right);
        }
    }
    int main()
    {
        Tree T=NULL,p;
        int a[]={5,6,7,2,4,10};
        for(int i=0;i<sizeof(a)/sizeof(a[0]);i++)
            Insert(T,a[i],p);
            Traverse(T);
            DeleteBSF(T,4);
            cout<<"删除结点后:"<<endl;
            Traverse(T);
            return 0;
    }
  • 相关阅读:
    java这个404你能解决吗?
    java发邮件,这个坑你能填吗?
    自动评论csdn博客文章实现
    一款效率神器Ditto
    java加载国际化文件的几种姿势
    这个问题你能答对吗?
    mysql大小写敏感与校对规则
    java、golang日志文件转储压缩实现
    一款很好用的markdown编辑器
    beego与curl三件事
  • 原文地址:https://www.cnblogs.com/tinaluo/p/5303096.html
Copyright © 2011-2022 走看看