【问题标题】:Trouble trying to eliminate a node from a tree (struct)尝试从树(结构)中消除节点时遇到问题
【发布时间】:2017-09-22 17:34:38
【问题描述】:

正如标题所说,我正在尝试从具有 2 个案例的树中删除一个节点:

  • 节点是没有连接到任何东西的叶子
  • 节点连接到另一个节点

我能够为第二种情况(对我来说最困难)创建一个工作函数,但第一种情况(这似乎很容易)无论我尝试什么都会导致分段错误。

结构体的定义如下:

struct node {
    int value;
    struct node *sx;
    struct node *dx;
};

typedef struct node *tree;

这是执行消除操作的模块:

void destroy_node(tree Y, int elem) {
    if (Y->value < elem)
        destroy_node(Y->dx, elem);
    if (Y->value > elem)
        destroy_node(Y->sx, elem);
    else { //
        if (Y->sx == NULL && Y->dx == NULL) {
            free(Y); <-- seg fault
            Y = NULL; <-- seg fault
        }
        if (Y->sx != NULL && Y->dx == NULL) {
            Y->value = (Y->sx)->value;
            free(Y->sx);
            Y->sx = NULL;
        }
        if (Y->sx == NULL && Y->dx != NULL) {
            Y->value = (Y->dx)->value;
            free(Y->dx);
            Y->dx = NULL;
        }
        if (Y->sx != NULL && Y->dx != NULL)
            printf("Can't eliminate that!\n");
    }
    print_everything(Y);
}

这里是main 电话:

tree Y = T;
printf("Which one you want to destroy?  ");
scanf("%d", &elem);
destroy_node(Y, elem);

要编译我使用命令的函数

gcc -std=gnu99 -Wall -Wextra c.c 

我的环境是虚拟机 ubuntu 17.04 with stock gcc

编辑 1

构建树的模块

tree insert_node(tree T, int val) {
    if (T == NULL) {    
        T = (tree)malloc(sizeof(struct node));
        T->value = val;
        T->sx = NULL;
        T->dx = NULL;
    } else {
        if ((T->value) < (val)) {
            T->dx = insert_node(T->dx, val);
        }
        if ((T->value) > (val)) {
            T->sx = insert_node(T->sx, val);
        }
    }
    return T;
}

这里有这个模块main中的调用

printf("How many nodes your tree will have?  ");
scanf("%d", &tot);
for (int i = 0; i < tot; i++) {
    printf("What is the %d° node?  ", (i + 1));
    scanf("%d", &val);
    T = insert_node(T, val);
}

附:如果程序的可理解性有问题,我会复制粘贴整个文件

【问题讨论】:

  • 你能添加你构建树的部分吗?
  • @atru 插入了您要求的其他功能,希望对您有所帮助
  • 您忘记检查Y 是否为空。
  • 隐藏类型定义后面的指针?嗯。

标签: c struct tree


【解决方案1】:

您的函数中缺少部分:

  • 你不检查Y != NULL。在一棵空树上会有未定义的行为。
  • 在第一个 if 语句之后缺少 else。如果Y-&gt;value &lt;= elem,您错误地删除了该节点。
  • 删除节点时不会更新父指针。

您应该更改 API 以返回指针参数的更新值:

tree destroy_node(tree Y, int elem) {
    tree res = Y;
    if (Y != NULL) {
        if (Y->value < elem) {
            Y->dx = destroy_node(Y->dx, elem);
        } else
        if (Y->value > elem) {
            Y->sx = destroy_node(Y->sx, elem);
        } else {
        if (Y->dx == NULL) {
            res = Y->sx;
            free(Y);
        } else
        if (Y->sx == NULL) {
            res = Y->dx;
            free(Y);
        } else {
            printf("Can't eliminate that!\n");
        }
    }
    return res;
}

main致电:

tree T;
...
printf("Which one you want to destroy? ");
if (scanf("%d", &elem) == 1)
    T = destroy_node(T, elem);

当然你必须找到一个解决方案来删除具有 2 个分支的节点。

【讨论】:

  • 使用它立即使我的代码工作。显然,我会找到一个删除具有 2 个分支的节点的解决方案,但我通常会尝试从一个小代码开始工作,然后添加新函数以避免过多的混淆(和错误)。顺便说一句谢谢
  • @Allen:这是一个好方法。重新阅读代码,我意识到if (Y-&gt;sx == NULL &amp;&amp; Y-&gt;dx == NULL) 测试是多余的。答案更新和简化。
猜你喜欢
  • 1970-01-01
  • 2019-01-25
  • 2015-03-16
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多