简体   繁体   中英

C++ delete min element in binary tree

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM