Binary Search Tree delete function not working properly - c++

I am working with a binary search tree and am attempting to create a function to delete a single node. For some reason certain nodes will not delete (most of the seem to be instances that have a right node but not a left) but exactly what node won't delete seems pretty haphazard which makes it difficult to debug. Occasionally I will get the error
mov(30071,0x7fff73b1d300) malloc: *** error for object 0x7fcb2b404f40: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
but most of the time the node just doesn't delete and the program continues to run.
Here is my delete function:
Node* Tree::deleteNode(Node *node,string title)
{
if(node == NULL){
return node;
}
else if(node->title.compare(title) > 0){
node->left = deleteNode(node->left, title);
}
else if(node->title.compare(title) < 0){
node->right = deleteNode(node->right, title);
}
else
{
//No Child
if(node->left == NULL && node->right == NULL){
if(node == node->parent->right)
{
node->parent->right = NULL;
}
else
{
node->parent->left = NULL;
}
node = NULL;
}
//One child
else if(node->left == NULL)
{
//Here is where some fail
Node *temp = node;
node = node->right;
delete temp;
}
else if(node->right == NULL)
{
Node *temp = node;
node = node->left;
delete temp;
}
else
{
Node *temp = treeMinimum(node->right);
node->title = temp->title;
node->right = deleteNode(node->right, temp->title);
}
}
return node;
}
and:
Node* Tree::treeMinimum(Node *node)
{
while(node->left != NULL)
{
node = node->left;
}
return node;
}
It is always the same Nodes that won't delete but other nodes that are the same structurally (no left node, yes right node) delete no problem. The program always starts with the same tree of 50 nodes. I apologize if this information isn't suffice, please let me know if there is anything else I can provide. Thank you

Related

Exception thrown: read access violation.during BST Deletion for many elements

so am having problems with the exception during deletion(Exception thrown: read access violation.
parent was 0x158398.)like that sometimes are different numbers etc and always its about parent object/pointer, my code is working without any errors,exceptions till 100k objects then sometimes works sometimes not, for 1 milion is not even working anymore.If anybody could help out would be great. under post am posting code:
Node Class:
template <class T>
class Node {
public:
T data;
Node<T>* Left = NULL;
Node<T>* Right = NULL;
};
the code for finding min of right subtree:
Node<T>* findMin(Node<T>* node)
{
while (node->Left != NULL)
node = node->Left;
return node;
}
code for Deletion:
void Delete(Node<T>*& node) {
if (node == NULL)
return;
Node<T>* parent = findParentForDelete(this->root, node);
Node<T>* temp = NULL;
//leafs
if (node->Left == NULL && node->Right == NULL) {
if (node == root) {
delete root;
root = NULL;
return;
}
else {
if (parent->Left == node) //line with exception
parent->Left = NULL;
else
parent->Right = NULL;
delete node;
node = NULL;
return;
}
}
//1 child left not null
else if (node->Left != NULL && node->Right == NULL)
{
if (node == root) {
temp = root->Left;
delete root;
root = NULL;
root = temp;
return;
}
else {
if (parent->Left == node)
parent->Left = node->Left;
else
parent->Right = node->Left;
delete node;
node = NULL;
return;
}
}
//1 child Right not null
else if (node->Left == NULL && node->Right != NULL)
{
if (node == root) {
temp = root->Right;
delete root;
root = NULL;
root = temp;
return;
}
else {
if (parent->Left == node)
parent->Left = node->Right;
else
parent->Right = node->Right;
delete node;
node = NULL;
return;
}
}
//2 childs
else if (node->Left != NULL && node->Right != NULL)
{
temp = findMin(node->Right);
T data = temp->data;
Delete(temp);
node->data = data;
}
}
finding parent:
Node<T>* findParentForDelete(Node<T>* node, Node<T>*& nodeToFind)
{
if (node == NULL)
return NULL;
if (node->Left == NULL && node->Right == NULL)
return NULL;
if ((node->Left != NULL && node->Left == nodeToFind)
|| (node->Right != NULL && node->Right == nodeToFind))
return node;
if (node->data->age > nodeToFind->data->age)
return findParentForDelete(node->Left, nodeToFind);
if (node->data->age < nodeToFind->data->age)
return findParentForDelete(node->Right, nodeToFind);
}
findParentForDelete does not always return a value.
It will not return a value if the node you're looking for has an age that is the same as a different node in the tree, so the value returned to the caller will be a garbage value.
If you increase the warning level when you compile, most compilers will issue a warning for this.

C++ trouble deleting nodes with only one child in BST

I'm having difficulty deleting a node in my binary search tree. The delete function is part of my Node class, and my findMin function is as well. Below is my delete function...
/**********************************************
* Delete
**********************************************/
node* node::Delete(node *root, string stuff)
{
//node *temp;
if (root == NULL) // Searches for value in tree
return NULL;
if (stuff < root->val) // String is in left subtree
root->left = Delete(root->left, stuff);
else if (stuff > root->val) // String is in right subtree
root->right = Delete(root->right, stuff);
else
{ // No children
if ((root->left == NULL) && (root->right == NULL))
{
delete(root);
root = NULL;
}
else if ((root->right == NULL) && (root->left != NULL)) // One left child node
{
node *temp = root;
root = root->left;
delete temp;
temp = NULL;
}
else if ((root->left == NULL) && (root->right!= NULL)) // One right child node
{
node *temp = root;
root = root->right;
delete temp;
temp = NULL;
}
else // Two children
{
node *temp = findMin(root->right); // Finds smallest value in right subtree
root->val = temp->val;
root->right = Delete(root->right, temp->val);
}
}
return root;
}
Below is my Destructor, which is giving me a SIGABRT (I'm using Xcode)
/**********************************************
* Destructor
**********************************************/
node::~node()
{
if (left != NULL) delete left;
if (right != NULL) delete right;
}
What my code is actually doing is not only deleting the node I intend to delete, but its child node. What could I be doing wrong? Is it an error with memory allocation? Is it an error with how I set the value to the child node?
You need to null your pointers to left and right before deleting a node.
You call:
node *temp = root;
root = root->left;
delete temp;
temp = NULL;
When you "delete temp" you are deleting a node which still points to root->left and root->right and your destructor insures they are also removed. You should instead do something like this:
node *temp = root;
root = root->left;
temp->left = NULL;
temp->right = NULL;
delete temp;
temp = NULL;
Also in your destructor you don't need to check if they are equal to null since delete already preforms this check.

How to combine findMin() and delete() to remove smallest node in a BST?

I have a recRemove function that recursively removes the given node. I also have a findMin function that finds the smallest node in the BST. I'm having trouble merging the two so that I can remove the smallest(or largest) node. This is what I tried doing but it just returned garbage: Full code: https://pastebin.com/HCVsUZ4S
//remove min node in BST
node * extractMin()
{
return recRemove(root, findMin(root));
}
//delete node from tree
node * recRemove(node * root, double data)
{
//3 cases: no children, one child, 2 children
if (root == NULL)
{
return NULL;
}
else if (data < root->data)
{
root->left = recRemove(root->left, data);
}
else if(data > root->data)
{
root->right = recRemove(root->right, data);
}
else
{
if (root->right == NULL && root->left == NULL) //no children
{
delete root;
root = NULL;
return root;
}
else if(root->left == NULL) //only right child
{
temp = root;
root = root->right;
delete temp;
return root;
}
else if(root->right == NULL) //only left child
{
temp = root;
root = root->left;
delete temp;
return root;
}
else //2 children
{
temp->data = findMin(root->right);
root->data = temp->data;
root->right = recRemove(root->right, temp->data);
}
}
return root;
}
//find min node in BST
double findMin(node * p)
{
if(p == NULL)
{
return -1;
}
else
{
//in a balanced BST the minimum node is the leftmost node so,
//we traverse the left subtree until we get to the leftmost node and return and remove it.
temp = p;
while(temp->left != NULL)
{
temp = temp->left;
}
return temp->data;
}
}
sorry , can't write comments yet (will delete this later)
Where is temp defined? If it is a global variable than this is probably the issue...
Edit:
Have now seen the pasebin.....
temp is a member variable. Change it to a local variable.
Make sure to delete it before leaving the function. (best use std::unique_ptr<>)

Deleting the root node of a BST

I'm trying to make a remove function (without the use of recursion), that passes in the value of the node I want to remove.
My current problem is that my destructor seems to be making the program crash (getting a runtime error), which is probably because I'm not deleting the root node properly in my remove function.
The code I'm trying to use to remove the root is here:
bool BST::remove_root (int val)
{
if (val == root_->val)
{
if (root_->left == NULL && root_->right != NULL)
{
Node* temp = root_->right;
delete root_;
root_ = NULL;
size_--;
root_ = temp;
return true;
}
else if (root_->right == NULL && root_->left != NULL)
{
Node* temp = root_->left;
delete root_;
root_ = NULL;
size_--;
root_ = temp;
return true;
}
else
{
Node *curr = root_->right, *child = root_->left;
delete root_;
root_ = NULL;
size_--;
root_ = curr;
Node* temp = curr;
while (temp->left != NULL)
temp = temp->left;
temp->left = child;
return true;
}
}
}
In my code, just using val by itself is the value being passed in to the remove function (the one I want to remove). When I dereference things like root_->val, I'm accessing the val in my BST class.
I don't really understand why this wouldn't be able to continuously delete the root node (like I said I think it's the destructor making the program crash), but I feel like it could be invalid pointers?

Remove a Node from a binary tree

Please help. What is wrong with my remove function below. Cant seem to figure it out
I seem to be getting an error:
The class declaration seems pretty fine. The main issue is to have this remove function to work
void binaryTree::Remove(int) {
if (node != NULL)
{
Node* tmptr = node;
int rootdata = node->data;
/int rSubtree;
}
{
// Case 0- no child
if (node->lChild == NULL && node->rChild == NULL)
{
node = NULL;
//parent- //set the parent of the node to NULL
delete node;
}
// has one child
else if (node->lChild == NULL && node->rChild != NULL)
{
node = node->rChild;
node->rChild = NULL;
delete node;
}
else if (node->lChild != NULL && node->rChild == NULL)
{
node = node->lChild;`enter code here`
node->lChild = NULL;
delete node;
}
}
Try swapping node = NULL with delete node; Otherwise you're trying to delete NULL.