在C中的二进制搜索树中删除

时间:2013-03-07 07:29:53

标签: c binary-tree binary-search-tree

我在C中实现了BST。插入和查找工作正常。但删除根节点时删除存在问题。我无法释放指向根节点的指针。如果我将它作为双指针传递,我可以,但我想保持代码简单而不使用双指针。这里我没有指向根节点的头指针。我应该使用指向根节点的头指针吗?

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node* left;
    struct node* right;
};
struct node* newNode(int data)
{
    struct node* node = malloc(sizeof(struct node));
    node->data=data;
    node->left=NULL;
    node->right=NULL;
    return(node);
}

static int lookup(struct node* node,int target)
{
    if(node==NULL)
    {
        return(0);
    }
    else
    {
        if(target == node->data)
        {
            return(1);
        }
        else
        {
            if(target < node->data)
            {
                return(lookup(node->left,target));
            }
            else
            {
                return(lookup(node->right,target));
            }
        }
    }
}


struct node* insert(struct node* node, int data)
{
    if(node==NULL)
    {
        return(newNode(data));
    }   
    else
    {
        if(data < node->data)
        {
            node->left =insert(node->left,data);
        }
        else
        {
            node->right=insert(node->right,data);
        }
        return(node);
    }
}

struct node* delete(struct node* node, struct node* pnode, int target)
{
    struct node* rchild;
    struct node* rchildparent;
    if(node==NULL)
    {
        return(pnode);
    }
    else
    {
        if(target == node->data)
        {
            if(node->left == NULL && node->right == NULL) //leaf node
            {
                if(pnode == NULL) //special case deleting the root node
                {
                    free(node);
                    return(NULL);
                }
                if(pnode->left == node)
                {
                    pnode->left = NULL;
                }
                else
                {
                    pnode->right = NULL;
                }
                free(node);
                return(pnode);
            }
            if(node->left ==NULL ) //one child
            {
                if(pnode == NULL) //deleting root having no left child
                {
                    struct node* temp = node;
                    node = node->right;
                    free(temp);
                    return(node);
                }
                if(pnode->left == node)
                {
                    pnode->left = node->right;
                }
                else
                {
                    pnode->right = node->right;
                }   
                free(node);
                return(pnode);
            }
            if(node->right ==NULL ) //one child
            {
                if(pnode == NULL) //deleting root having no right child
                {
                    struct node* temp = node;
                    node = node->left;
                    free(temp);
                    return(node);
                }
                if(pnode->left == node)
                {
                    pnode->left = node->left;
                }
                else
                {
                    pnode->right = node->left;
                }   
                free(node);
                return(pnode);
            }

            //two children case
            rchild = node->right;
            rchildparent=node;
            while(rchild->left != NULL)
            {
                rchildparent=rchild;
                rchild = rchild->left;
            }
            node->data=rchild->data;
            if(rchildparent == node)
            {
                //rchildparent->right=rchild->right;
                node->right=rchild->right;
            }
            else
            {
                //rchildparent->left=NULL;
                rchildparent->left=rchild->right;
            }
            free(rchild);
            if(pnode ==NULL) //root node
            {
                return(node);
            }           
            return(pnode);
        }
        else
        {
            if(target < node->data)
            {
                delete(node->left,node,target);
                return(node);
            }
            else
            {
                delete(node->right,node,target);
                return(node);
            }
        }

    }

}
void printinorder(struct node* node)
{
    if(node == NULL)
    {
        return;
    }   
    printinorder(node->left);
    printf("%d\t",node->data);
    printinorder(node->right);
}
int main()
{
    clock_t start,end;
    struct node* root = newNode(3);
    insert(root,7);
    insert(root,7);
    insert(root,7);
    printinorder(root);
    printf("\n");
    root = delete(root,NULL,6);
    printinorder(root);
    printf("\n");
}

编辑: 根据@ modifiable lvalue建议修复了代码。现在有一种方法可以改进删除逻辑吗?

3 个答案:

答案 0 :(得分:1)

我会从delete中返回头节点,并在主函数中管理头部,如:root = delete(root, NULL, 10);,我会对insert:root = insert(root,/*...*/);执行相同操作,因为它有点像看起来你已经完成了......

答案 1 :(得分:0)

私有DataNode删除(DataNode root,int dValue){

RSolr::Error::Http (RSolr::Error::Http - 500 Internal Server Error
Error: {'error'=>{'msg'=>'java.lang.AbstractMethodError','trace'=>'java.lang.RuntimeException: java.lang.AbstractMethodError

}

私有DataNode MinBST(DataNode root){

DataNode temp=null;
if(root!=null){
    if(dValue<root.value){
        root.left=delete(root.left,dValue);
    }
    else if(dValue>root.value){
        root.right=delete(root.right,dValue);
    }
    else{
           if(root.left==null){
                temp=root.right;
               root.right=null;
               return temp;
           }
           else if(root.right==null){
               temp=root.left;
               root.left=null;
               return temp;
           }

           temp=MinBST(root.right);
           root.value=temp.value;
           //deleting inorder successor
           root.right=null;
    }
}
return root;

}

浏览链接以从二叉树中删除节点

https://www.youtube.com/watch?v=YK3tLMYk3nk

答案 2 :(得分:0)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1477112217000",
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "arn:aws:sns:ap-southeast-2:012345678912:My-SNS-Topic"
            ]
        }
    ]
}