【问题标题】:Remove elements from a binary search tree based on a condition根据条件从二叉搜索树中删除元素
【发布时间】:2021-11-10 23:16:38
【问题描述】:

我有一个存储文件名和上次访问日期的结构。

typedef struct sFile {
   int lastAccess;
   char name[50];
} File;

typedef struct sNode {
   File info;
   struct sNode* left;
   struct sNode* right;
} Node;

我编写了一个函数,该函数递归地删除访问天数小于特定数字的文件。例如调用该函数并传入 10 作为参数,所有访问天数小于 10 的文件都会被删除。

但是,我在执行相同的操作时遇到了问题,最终产生了内存访问错误。

我相信我的插入和删除函数是正确的,但以防万一我把它们留在下面。

插入和删除函数:

void insert(Node **root, File value) {
   if(*root == NULL) {
      Node *celula = getNode();
      
      if(celula == NULL) {
         printf("\nERRO: Falha na alocacao de memoria. Encerrando programa.\n");
         exit(1);
      }

      celula->left = NULL;
      celula->right = NULL;
      celula->info = value;
      *root = celula ;
   } else {
      if(strcmp(value.name, (*root)->info.name) < 0) {
         insert(&(*root)->left, value);
      } else {
         insert(&(*root)->right, value);
      }
   }
};

Node* deleteNode(Node *root, char name[50]) {
    if (root == NULL)
        return root;
 
    if (strcmp(name, root->info.name) < 0)
        root->left = deleteNode(root->left, name);
 
    else if (strcmp(name, root->info.name) > 0)
        root->right = deleteNode(root->right, name);
 
    else {
        if (root->left == NULL) {
            Node *temp = root->right;
            free(root);
            return temp;
        }
        else if (root->right == NULL) {
            Node *temp = root->left;
            free(root);
            return temp;
        }
 
        Node *temp = minValueNode(root->right);
 
        root->info = temp->info;
 
        root->right = deleteNode(root->right, temp->info.name);
    }
    return root;
}

树木清理功能:

Node* clear(Node *root, int date) {
   if(root == NULL) {
      return NULL;
   }

   if(root->info.lastAccess <= date) {
      root = deleteNode(root, (root)->info.name);
   }

   root = clear(root->left, date);
   root = clear(root->right, date);

   return root;
}

错误信息:

[1]    39970 segmentation fault (core dumped)  ./7.out

有谁知道可能导致此错误的原因以及如何修复它?

【问题讨论】:

  • 我不明白这两条 root = clear(... 行的意义。肯定要做的一件事是学习如何将核心转储加载到 gdb 中,这样您就可以看到导致故障的行。该行中的某些指针是垃圾。另一点建议是提供可以显示问题的最小完整程序。这是获得帮助的最佳方式。

标签: c recursion data-structures binary-search-tree recursive-datastructures


【解决方案1】:

我能够找到错误。感谢所有提供帮助的人。

我将 NULL 返回到树的根,因此我丢失了所有树引用,因此执行了不正确的内存访问。我将 clear 函数更新为以下内容:

Node* clear(Node *root, int date) {
   if(root == NULL) {
      return NULL;
   }

   if(root->info.lastAccess <= date) {
      root = deleteNode(root, (root)->info.name);
   }

   root->left = clear(root->left, date);
   root->right = clear(root->right, date);

   return root;
}

【讨论】:

    【解决方案2】:

    我建议运行 valgrind、gdb 等来尝试找出错误的确切位置,但如果没有这些信息,我可以在此处看到可能的 NULL 取消引用。

    如果root-&gt;leftroot-&gt;right 都为NULL,则deleteNode 将返回NULL,然后通过对clear(root-&gt;left, date) 的调用取消引用。

    看看是否在此处插入一个 NULL 检查是否会使其不再出现段错误。

    同样,这里无法判断是否是导致它的原因,还请提供其余代码以使其可运行,或调试它以找出导致段错误的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      相关资源
      最近更新 更多