如何实现N叉树完整分支删除?解决递归删除后的指针悬空问题
我明白你的问题所在——现有的delete_branch函数只负责递归释放节点内存,但完全没处理上层节点指向被删除分支的指针,这就导致释放后那些指针变成野指针,进而引发内存访问错误。
要解决这个问题,我们需要修改函数,让它能同时更新上层的指向指针。核心思路是使用**双重指针(指向节点指针的指针)**作为参数,这样我们就能在释放节点的同时,把上层的指针重新指向被删除节点的兄弟,彻底切断野指针的来源。
第一步:修正delete_branch函数
重构后的函数需要完成两个核心任务:
- 递归释放目标节点的所有子节点(整个子树)
- 更新上层指向目标节点的指针,让它指向目标节点的兄弟,同时释放目标节点
代码实现如下:
#include <stdlib.h> typedef struct node { char data; struct node *child; struct node *sibling; }*tree; void delete_branch(tree *target_ptr) { if (*target_ptr == NULL) { return; } // 先递归删除当前节点的所有子节点(整个子树) delete_branch(&(*target_ptr)->child); // 保存当前节点的兄弟节点,用于后续更新上层指针 tree next_sibling = (*target_ptr)->sibling; // 释放当前节点的内存 free(*target_ptr); // 更新上层指针,让它指向当前节点的兄弟,避免野指针 *target_ptr = next_sibling; }
第二步:找到指向目标节点的指针
你已经有了查找节点地址的函数,但我们需要的是指向该节点的指针的地址(也就是双重指针)——因为只有这样,delete_branch才能修改上层的指向。这里提供一个辅助查找函数:
tree* find_node_ptr(tree *root, char data) { if (*root == NULL) { return NULL; } // 当前节点就是目标,返回指向它的指针 if ((*root)->data == data) { return root; } // 先在子节点链中查找 tree* child_result = find_node_ptr(&(*root)->child, data); if (child_result != NULL) { return child_result; } // 再在兄弟节点链中查找 return find_node_ptr(&(*root)->sibling, data); }
第三步:使用示例
比如你要删除data为'B'的节点及其分支,可以这样调用:
// 假设root是你的N叉树根节点 tree *target_ptr = find_node_ptr(&root, 'B'); if (target_ptr != NULL) { delete_branch(target_ptr); }
为什么这样能解决问题?
拿你的例子来说:
- 原来根节点R的
child指向B,B的sibling指向C - 调用
delete_branch(&R->child)时,函数会先删除B的所有子节点(E、F),然后释放B,最后把R->child设置为C - 这样R的
child就正确指向了C,不会再指向已经被释放的B,彻底解决了野指针问题
内容的提问来源于stack exchange,提问作者Real
相关产品推荐
相关产品推荐

