我具有以下用于删除min元素的功能:
int BinaryTree::delete_min_helper(TreeNode *node){
while(node->left != NULL){
node = node->left;
}
if(node == root){
return 1;
}
delete node;
node = NULL;
return 0;
}
我总是将指向根节点的指针传递给该函数。我已经尝试过此方法及其一些变体,但它似乎总是删除错误的内容或根本不删除任何内容。有什么想法吗?
这是一个可编译的示例:
#ifndef _TREE_H_
#define _TREE_H_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct TreeNode {
int val;
char *str;
TreeNode *left;
TreeNode *right;
};
class BinaryTree {
public:
BinaryTree();
~BinaryTree();
int insert_node(unsigned int val, char *str);
TreeNode *find_min();
int delete_min();
void print();
private:
int insert_node_helper(TreeNode *&node, unsigned int val, char *str);
int delete_min_helper(TreeNode *node);
void print_helper(TreeNode *node);
TreeNode *root;
};
#endif
BinaryTree::BinaryTree(){
this->root = NULL;
}
BinaryTree::~BinaryTree(){
}
int BinaryTree::insert_node(unsigned int val, char *str){
return insert_node_helper(this->root, val, str);
}
int BinaryTree::insert_node_helper(TreeNode *&node, unsigned int val, char *str){
if(node == NULL){
node = new TreeNode;
node->val = val;
node->str = strdup(str);
node->left = NULL;
node->right = NULL;
if(node != NULL){
return 0;
}else{
puts("inserted null node");
return 1;
}
}else if(val <= node->val){
return insert_node_helper(node->left, val, str);
}else if(val > node->val){
return insert_node_helper(node->right, val, str);
}
return 1;
}
void BinaryTree::print(){
print_helper(this->root);
}
void BinaryTree::print_helper(TreeNode *node){
if(node != NULL){
print_helper(node->right);
printf("%d occurrences of \"%s\"\n", node->val, node->str);
print_helper(node->left);
}
}
TreeNode *BinaryTree::find_min(){
TreeNode *temp = this->root;
while(temp->left != NULL){
temp = temp->left;
}
return temp;
}
int BinaryTree::delete_min(){
return delete_min_helper(root);
}
int BinaryTree::delete_min_helper(TreeNode *node){
while(node->left != NULL){
node = node->left;
}
if(node == root){
puts("attempted to delete root");
return 1;
}
delete node;
node = NULL;
return 0;
}
#include <time.h>
int main(){
BinaryTree bt;
srand(time(NULL));
for(int i = 0; i < 10; i++){
bt.insert_node(rand() % 20, "test");
}
bt.print();
printf("min val = %d\n", bt.find_min()->val);
puts("#################################");
bt.delete_min();
bt.print();
printf("min val = %d\n", bt.find_min()->val);
return 0;
}
最佳答案
您正在将对指针的引用作为参数(TreeNode *&node
),然后对其进行修改。因此,如果将树的根传递给此方法,则最终会将根设置为NULL
。
另外,这实际上绝对不会删除任何内容,因为在将指针设置为NULL后调用了delete,并且在空指针上调用的delete
不会执行任何操作。
编辑原始帖子后更新:
我假设root
是BinaryTree的成员。如果发布了Short, Self Contained, Compilable Example,将更容易为您提供帮助。
您仍在扎根作为参考。因此,node == root
将始终为真,并且您将永远不会到达delete
语句。因此,实际上您没有删除任何内容,而是将根更改为最左侧的子节点。
尝试将您的方法签名更改为
int BinaryTree::delete_min_helper(TreeNode *node){
也就是说,没有与号(
&
)。编辑后:
好的,现在我运行了您的程序,并找到了第二个问题。在行中
node = NULL;
您正在更改本地指针的值,而不是父节点中
left
指针的值。这意味着,当您下次遍历该树时,将访问指向刚删除的内存的指针。这会触发不确定的行为。为了解决这个问题,在删除叶节点时,应将父节点的left
指针设置为0。