I have the following function for deleting the min element:
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;
}
I always pass a pointer to the root node to this function. I've tried this and a few variations of it, but it always seems to delete the the wrong thing or not delete anything at all. Any ideas why?
Here is a compilable example:
#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;
}
You are taking a reference to a pointer as argument ( TreeNode *&node
), and then modify it. So if you pass the root of your tree to this method, you will eventually set the root to NULL
.
Additionally this actually deletes absolutely nothing, because you call delete after setting the pointer to NULL, and delete
called on a null-pointer does nothing.
Update after edit of original post:
I assume root
is a member of BinaryTree. It would be easier to help you if you posted a Short, Self Contained, Compilable Example .
You're still taking root as a reference. Thus node == root
will always be true, and you'll never reach your delete
statement. So actually you're not deleting anything, but you're changing your root to be the left-most child node.
Try changing your method signature to
int BinaryTree::delete_min_helper(TreeNode *node){
that is, without the ampersand ( &
).
After edit:
Ok, now I've run your program, and found your second problem. In the line
node = NULL;
You're changing the value of a local pointer, not of the left
-pointer in the parent node. This means than when you traverse the tree the next time, you will access a pointer to the memory you just deleted. That triggers undefined behaviour. To get around this you should set the left
-pointer of your parent node to 0 when you delete your leaf-node.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.