Remove a Node from a binary tree - c++

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.

Related

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.

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?

Binary Search Tree delete function not working properly

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

Linked list deleting last node c++

I am currently writing some code which will delete the last node from a linked list, i have the code below; but it is deleting the previous node to the last node; not the last node itself.
Any help will be appreciated:
if(p!=NULL) {
if( p->next!=NULL) {
Student *todel = p->next;
p->next= p->next->next;
delete todel; //free(todel);
} else {
delete p; //If n = 0 && its the last element, delete it
}
}
EDIT:
I have now edited this code to look like the below......it is not working; is it because I am pointing to a NULL vaue, then deleting that null value?
if(p!=NULL) {
if( p->next==NULL) {
delete p;
}
}
Check this one.
if(p!=NULL) {
if ( p->next!=NULL) {
while (1) {
Student *todel = p->next;
if (todel->next == NULL) {
// todel is indeed the last node, delete it
delete todel;
p->next = NULL;
break; // break from infinite while loop that was looking for last node
}
else {
// todel is not last node, go further
p = todel->next;
}
}
} else {
delete p; //If n = 0 && its the last element, delete it
}
}
Try the following instead inside the loop you are using to walk the linked list.
if(p->next!=NULL) {
if (p->next->next == NULL) {// Found the second-to-last-node
delete p->next; // Kill the last node
p->next = NULL; // Make the current node the last node.
}
}
Try this, I didn't test it.
void delete_lastnode(Node* head)
{
Node *p = head;
if (p == NULL) // NULL list
return;
if (p->next == NULL) // Single node list
{
delete head;
head = NULL;
return;
}
while(p->next->next != NULL) // Find the second-last node
{
p = p->next;
}
Node* temp = p->next;
p->next = NULL;
delete temp;
temp = NULL;
}

C++ - OOP implementation of linked list, I not sure why adding to end is not working for me, please advise

I am refreshing my knowledge of C++ OOP but not sure why I can get this traversal and adding to end of list up and running. Any advice on this context would be highly appreciated.
#include "stdafx.h"
#include "LinkedList.h"
LinkedList::LinkedList(void)
{
}
LinkedList::~LinkedList(void)
{
}
void LinkedList::add(Node* node)
{
Node* root = this->getRoot();
if(root !=NULL)
{
//with two nodes the commented code worked
//while(root->getNextNode() != NULL){}
//root->setNextNode(node);
//this part is culprit
Node* newNode = root->getNextNode();
while(newNode!=NULL)
{
newNode = newNode->getNextNode();
}
//I was thinking I am reaching to last node using this traversal
newNode = new Node(node->getData(),node->getNextNode());
}else
{
this->setRoot(node);
}
};
void LinkedList::traverseNodes()
{
Node* node = this->getRoot();
printf("\ntraversing the nodes:");
while(node != NULL){
printf("%d", node->getData());
node = node->getNextNode();
}
}
The problem with your code is that once you set the pointer newNode to NULL, pointing it to a new node won't change the previous last node.
Try this:
Node* root = this->getRoot();
if (root != NULL) {
Node* parent = root;
while(true) {
// two variables mean you have access to the previous node,
// which is needed to add the next one.
Node* child = parent->getNextNode();
if (child != NULL) {
parent = child;
} else {
parent->setNextNode(/* new node */);
break; // EDIT
}
}
} else //...
That fault is because you did not append at end, actually, you can fix the code by something like following
Node* previouseNode = this->getRoot();
while(previouseNode->getNextNode() != NULL)
{
previouseNode = previouseNode->getNextNode();
}
//Next node of previouseNode is null so you can assign to it
Node * newNode = new Node(node->getData(), previouseNode); // Maybe your list is bi-directional!
previouseNode->setNextNode(newNode);
When you have reached NULL it is too late, you need to keep track of the node before.
void LinkedList::add(Node* node) {
Node* current = this->getRoot();
if (current != NULL) {
while(current->getNextNode() != NULL) {
current = current->getNextNode();
}
current->setNextNode(node);
} else {
this->setRoot(node);
}
};