C语言:从字符串的BST中删除一个节点

Posted

技术标签:

【中文标题】C语言:从字符串的BST中删除一个节点【英文标题】:C language:Removing a node from a BST of strings 【发布时间】:2021-07-11 19:02:21 【问题描述】:

我正在尝试编写一个函数,该函数将从 BST 中删除一个节点,该节点将是==,带有用户在程序中插入的单词,这意味着我问用户,他想要哪个单词要删除,他将其输入并保存在变量key[MAX]main。但是尝试删除节点时出现问题,所以我的程序就死了

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 15

typedef struct BST

    char data[MAX];
    struct BST *left;
    struct BST *right;
    int count;
 node;

node *create();
void insert(node *,node *);
void preorder(node *);
struct BST *minValueNode(struct BST *node)

    struct BST *current = node;


    while (current && current->left != NULL)
        current = current->left;

    return current;

struct BST *deleteNode(struct BST *root, char key[MAX])


    if (root == NULL)
        return root;

    int cmp_rezult=strcmp(root->data, key[MAX]);

    if (key[MAX] < root->data[MAX])
        root->left = deleteNode(root->left, key);
    else if (key[MAX] > root->data[MAX])
        root->right = deleteNode(root->right, key);

    else
    
        if (root->left == NULL)//it the node has no children or only 1
        
            struct BST *temp = root->right;
            free(root);
            return temp;
        
        else if (root->right == NULL)
        
            struct BST *temp = root->left;
            free(root);
            return temp;
        

        //if the node have 2 kids
        struct BST *temp = minValueNode(root->right);

        //sorting
        root->data[MAX] = temp->data[MAX];

        //deleting
        root->right = deleteNode(root->right, temp->data[MAX]);
    
    return root;



int main()

    char key[MAX];
    char ch;
    node *root=NULL,*temp;

    do
    
        temp=create();
        if(root==NULL)
        
            root=temp;
        
        else
        
            insert(root,temp);
        
        printf("\nDo you want to enter more(y/n)?");
        ch=getch();

    
    while(ch=='y'||ch=='Y');

    printf("\nPreorder Traversal: ");
    preorder(root);
    printf("\nWho shall we delete:");
    scanf("%s", &key[MAX]);
    deleteNode(root, key[MAX]);
    return 0;


node *create()

    node *temp;
    printf("\nEnter data:");

    temp=(node*)malloc(sizeof(node));

    fgets(&temp->data,MAX,stdin);

    temp->left=temp->right=NULL;
    temp->count=1;
    return temp;


void insert(node *root,node *temp)

    int cmp_rezult=strcmp(temp->data,root->data);
    if(cmp_rezult<0)
    
        if(root->left!=NULL)
        insert(root->left,temp);
        else
        root->left=temp;
    
    if(cmp_rezult>0)
    
        if(root->right!=NULL)
        insert(root->right,temp);
        else
        root->right=temp;
    
    if(cmp_rezult==0)
    
        root->count++;
    


void preorder(node *root)

    if(root!=NULL)
    
        printf("\n%s Repeats:%d time(s)",root->data, root->count);
        preorder(root->left);
        preorder(root->right);
    

【问题讨论】:

实际上在任何地方都没有定义struct node。只有struct BST,这是键入node 的别名。例如。这段代码不可能编译,因为struct node 是一个神话。我会冒险并建议无论你在哪里获得这个,他们都使用不同的结构名称,而你永远不会将它们解析为你的。进一步的证据来自神话成员key,它同样不在您定义的节点类型中,但被反复引用。 @WhozCraig 不是真的,先生,我试图将它们重命名为 struct BST ... 但它仍然给我同样的错误 如果您按照您的要求进行操作,即代码中的任何位置(无论是在使用还是声明中)都不再提及任何struct node,则它不能可能给出“相同的错误” " 除非您不再编译相同的源代码。此代码中有 大量 其他错误,但如果没有引用 struct node,则该错误不可能出现 @WhozCraig 我已经更新了程序,所以现在编译时它没有给我任何错误,但它仍然无法按预期工作 @Vlad 不,我说您首先需要更好地了解数组的工作原理。但是好吧,这里有一个例子:if(key[MAX] &lt; root-&gt;data[MAX]) 它比较了char after keychar after root-&gt;datascanf("%s", &amp;key[MAX]); 将使printf 将输入存储到缓冲区末尾。事实上,你没有始终如一地这样做是货物崇拜编程的标志 【参考方案1】:

这与上面的代码基本相同,但是,在BST *deleteNode 中,我更新了cmp_result 的代码,所以现在它写得正确,之后我更新了cmp_result 下的if 语句,我也更新了同一个函数中的代码,从root-&gt;data[MAX] = temp-&gt;data[MAX];strcpy(root-&gt;data,temp-&gt;data);,这是正确的做法

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 15

typedef struct BST

    char data[MAX];
    struct BST *left;
    struct BST *right;
    int count;
 node;

node *create();
void insert(node *,node *);
void preorder(node *);
struct BST *minValueNode(struct BST *node)

    struct BST *current = node;


    while (current && current->left != NULL)
        current = current->left;

    return current;

struct BST *deleteNode(struct BST *root, char key[MAX])


    if (root == NULL)
        return root;

    int cmp_result = strcmp(key, root->data);

    if (cmp_result < 0)
        root->left = deleteNode(root->left, key);
    else if (cmp_result > 0)
        root->right = deleteNode(root->right, key);
    else
    

        if (root->left == NULL)
        
            struct BST *temp = root->right;
            free(root);
            return temp;
        
        else if (root->right == NULL)
        
            struct BST *temp = root->left;
            free(root);
            return temp;
        

        
        struct BST *temp = minValueNode(root->right);

        strcpy(root->data,temp->data);

        
        root->right = deleteNode(root->right, temp->data);
    
    return root;



int main()

    char key[MAX];
    char ch;
    node *root=NULL,*temp;

    do
    
        temp=create();
        if(root==NULL)
        
            root=temp;
        
        else
        
            insert(root,temp);
        
        printf("\nDo you want to enter more(y/n)?");
        ch=getch();

    
    while(ch=='y'||ch=='Y');

    printf("\nPreorder Traversal: ");
    preorder(root);
    printf("\n\nWho shall we delete:");
    fgets(key,MAX,stdin);
    printf("\n%s", key);
    deleteNode(root, key);
    printf("\nPreorder Traversal: ");
    preorder(root);
    return 0;


node *create()

    node *temp;
    printf("\nEnter data:");

    temp=(node*)malloc(sizeof(node));

    fgets(temp->data,MAX,stdin);

    temp->left=temp->right=NULL;
    temp->count=1;
    return temp;


void insert(node *root,node *temp)

    int cmp_rezult=strcmp(temp->data,root->data);
    if(cmp_rezult<0)
    
        if(root->left!=NULL)
            insert(root->left,temp);
        else
            root->left=temp;
    
    if(cmp_rezult>0)
    
        if(root->right!=NULL)
            insert(root->right,temp);
        else
            root->right=temp;
    
    if(cmp_rezult==0)
    
        root->count++;
    


void preorder(node *root)

    if(root!=NULL)
    
        printf("\n%s Repeats:%d time(s)",root->data, root->count);
        preorder(root->left);
        preorder(root->right);
    

【讨论】:

这不是关于 SO 的答案。这只是一个“代码转储”。请解释你做了什么。

以上是关于C语言:从字符串的BST中删除一个节点的主要内容,如果未能解决你的问题,请参考以下文章

这个 BST 节点删除算法是如何工作的?

c语言 从字符串中删除特定字符

C语言实现二叉查找树(BST)的基本操作

当我尝试从单链表中删除节点时,为啥我的 C 程序会崩溃

C语言从键盘输入一个字符串,并删除该字符串中所有大写字母字符

二叉搜索树的插入与删除(C语言)