C语言中二叉搜索树中的Delete

C语言中二叉搜索树中的Delete,c,binary-tree,binary-search-tree,C,Binary Tree,Binary Search Tree,我已经在C中实现了BST。插入和查找工作正常。但是删除根节点时,delete会出现问题。我无法释放指向根节点的指针。如果我将其作为双指针传递,我可以这样做,但我希望代码保持简单,而不使用双指针。这里我没有指向根节点的头指针。我应该使用指向根节点的头指针吗 #include<stdio.h> #include<stdlib.h> struct node { int data; struct node* left; struct node* right

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

#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");
}
#包括
#包括
结构节点
{
int数据;
结构节点*左;
结构节点*右;
};
结构节点*新节点(整型数据)
{
结构节点*节点=malloc(sizeof(结构节点));
节点->数据=数据;
节点->左=空;
节点->右=空;
返回(节点);
}
静态整型查找(结构节点*节点,整型目标)
{
if(node==NULL)
{
返回(0);
}
其他的
{
如果(目标==节点->数据)
{
申报表(1);
}
其他的
{
if(目标<节点->数据)
{
返回(查找(节点->左侧,目标));
}
其他的
{
返回(查找(节点->右侧,目标));
}
}
}
}
结构节点*插入(结构节点*节点,int数据)
{
if(node==NULL)
{
返回(newNode(data));
}   
其他的
{
if(数据<节点->数据)
{
节点->左=插入(节点->左,数据);
}
其他的
{
节点->右侧=插入(节点->右侧,数据);
}
返回(节点);
}
}
结构节点*delete(结构节点*node,结构节点*pnode,int目标)
{
结构节点*rchild;
结构节点*rchildparent;
if(node==NULL)
{
返回(pnode);
}
其他的
{
如果(目标==节点->数据)
{
if(node->left==NULL&&node->right==NULL)//叶节点
{
if(pnode==NULL)//删除根节点的特殊情况
{
自由(节点);
返回(空);
}
if(pnode->left==节点)
{
pnode->left=NULL;
}
其他的
{
pnode->right=NULL;
}
自由(节点);
返回(pnode);
}
if(node->left==NULL)//一个子节点
{
if(pnode==NULL)//删除没有剩余子级的根
{
结构节点*temp=节点;
节点=节点->右侧;
免费(临时);
返回(节点);
}
if(pnode->left==节点)
{
pnode->left=节点->右侧;
}
其他的
{
pnode->right=节点->右侧;
}   
自由(节点);
返回(pnode);
}
if(node->right==NULL)//一个子节点
{
if(pnode==NULL)//删除没有正确子级的根
{
结构节点*temp=节点;
节点=节点->左;
免费(临时);
返回(节点);
}
if(pnode->left==节点)
{
pnode->left=节点->left;
}
其他的
{
pnode->right=节点->left;
}   
自由(节点);
返回(pnode);
}
//两名儿童个案
rchild=节点->右侧;
rchildparent=节点;
while(rchild->left!=NULL)
{
rchildparent=rchild;
rchild=rchild->left;
}
节点->数据=rchild->数据;
if(rchildparent==节点)
{
//rchildparent->right=rchild->right;
节点->右=rchild->右;
}
其他的
{
//rchildparent->left=NULL;
rchildparent->left=rchild->right;
}
免费(rchild);
if(pnode==NULL)//根节点
{
返回(节点);
}           
返回(pnode);
}
其他的
{
if(目标<节点->数据)
{
删除(节点->左侧,节点,目标);
返回(节点);
}
其他的
{
删除(节点->右侧,节点,目标);
返回(节点);
}
}
}
}
无效打印顺序(结构节点*节点)
{
if(node==NULL)
{
返回;
}   
打印顺序(节点->左侧);
printf(“%d\t”,节点->数据);
打印顺序(节点->右侧);
}
int main()
{
时钟开始、结束;
结构节点*root=newNode(3);
插入(根,7);
插入(根,7);
插入(根,7);
打印顺序(根);
printf(“\n”);
root=delete(root,NULL,6);
打印顺序(根);
printf(“\n”);
}
编辑:
根据@
可修改左值
建议修复代码。现在有没有改进删除逻辑的方法?

我将从delete返回head节点,并在主函数中管理head,如:
root=delete(root,NULL,10),我会对insert做同样的操作:
root=insert(root,/*…*/),因为它看起来有点像你已经完成了…

私有数据节点删除(数据节点根,int-dValue){

}

通过链接从二叉树中删除节点

//c树
#包括
#包括
结构树节点
{
结构树节点*右,*左;
int数据;
};
结构树节点*savetemp=NULL;
结构树节点*del(结构树节点*,int);
结构树节点*插入(结构树节点*,int);
结构树节点*旅行(结构树节点*,结构树节点*);
void索引(结构树节点*);
整数高度(结构树节点*);
int noOfNode(结构树节点*);
void main()
{
结构树节点*root=NULL;
国际项目,cho;
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;
if(root!=null){
    while(root.left!=null){
        root=root.left;
    }
}
return root;
//c tree
#include<stdio.h>
#include<conio.h>
struct tree_node
{
    struct tree_node*right,*left;
    int data;
};
struct tree_node*savetemp=NULL;
struct tree_node* del(struct tree_node*,int);
struct tree_node* insert(struct tree_node*,int);
struct tree_node* travel(struct tree_node*,struct tree_node*);
void inorder(struct tree_node *);
int height(struct tree_node*);
int noOfNode(struct tree_node *);
void main()
{
    struct tree_node* root=NULL;
    int item,cho;
    clrscr();
    do
    {
        printf("Enter your choice\n");
        printf("1.insert 2.delete 3.display 4.no of nodes 5.height 6.exit\n");
        scanf("%d",&cho);
        switch(cho)
        {
            case 1:{
                printf("Enter element to insert\n");
                scanf("%d",&item);
                root=insert(root,item);
            }
            break;
            case 2:{
                printf("Enter element to delete\n");
                scanf("%d",&item);
                root=del(root,item);
                if(savetemp!=NULL)//condition for any break link is present to insert or not
                travel(root,savetemp);//to insert break link during insertion
            }
            break;
            case 3:{
                printf("inorder travel\n");
                inorder(root);
            }
            break;
            case 4:{
                printf("No of nodes are: %d\n",noOfNode(root));
            }
            break;
            case 5:
            printf("height of tree %d",height(root));
            break;
            case 6:
            printf("Exiting");
            break;
            default : printf("wrong cho\n");
        }
    }while(cho!=6);
    getch();
}
void inorder(struct tree_node *root)
{
    if (root != NULL)
    {
    inorder(root->left);
    printf("%d \n", root->data);
    inorder(root->right);
    }
}
struct tree_node* insert(struct tree_node*root,int item)
{
    if(root==NULL)
    {
        struct tree_node* temp;
        temp=(struct tree_node*)malloc(sizeof(struct tree_node));
        temp->left=NULL;
        temp->right=NULL;
        temp->data=item;
        root=temp;
    }
    else
    {
            if(root->data<item)
            {
                root->right=insert(root->right,item);
            }
            else
            {
                root->left=insert(root->left,item);
            }
    }
    return(root);
}
struct tree_node* del(struct tree_node*root,int item)
{
    if(item==root->data)
    {
        if(root->left==NULL&&root->right==NULL) //no child
        {
            root=NULL;

        }
        else if(root->left==NULL||root->right==NULL) //one child
        {
            if(root->left!=NULL) //left child
            {
                root=root->left;
            }
            else               //right child
            {
                root=root->right;
            }
        }
        else  if(root->left!=NULL&&root->right!=NULL) //both child
        {
            struct tree_node* temp;
            savetemp=root->right->left;
            temp=root;
            root=root->right;
            root->left=temp->left;
        }
    }
    else
    {
            if(root->data<item)
            {
                root->right=del(root->right,item);
            }
            else
            {
                root->left=del(root->left,item);
            }
    }
    return(root);
}
struct tree_node* travel(struct tree_node*root,struct tree_node*savetemp)
{
    if (savetemp != NULL)
    {
        insert(root,savetemp->data);
        travel(root,savetemp->left);
        travel(root,savetemp->right);
    }
    return(root);
}
int height(struct tree_node*root)
{
    int lheight,rheight;
    if(root==NULL)
    {
        return(-1);
    }
        else
    {
        lheight=height(root->left);
        rheight=height(root->right);
    }
    if(lheight>rheight)
    {
        return(lheight+1);
    }
    else
    {
        return(rheight+1);
    }
}
int noOfNode(struct tree_node *root)
{
static int count=0;
    if (root != NULL)
    {
    noOfNode(root->left);
    count=count+1;
    noOfNode(root->right);
    }
    return(count);
}