Trouble deleting a node from Binary Search tree - c++

I am having trouble deleting a node from a binary search tree.
void BST::delete_node(Node* out)
{
Node* tmp;
Node* cur;
if(out->get_left() == NULL || out->get_right() == NULL) {
tmp = out;
}
else {
tmp = get_succ(out);
}
if(tmp->get_left() != NULL) {
cur = tmp->get_left();
}
else {
cur = tmp->get_right();
}
if(cur != NULL) {
cur->add_parent(tmp->get_parent());
}
if(tmp->get_parent() == NULL) {
root = cur;
}
else if(tmp == (tmp->get_parent())->get_left()) {
(tmp->get_parent())->add_left(cur);
}
else {
(tmp->get_parent())->add_right(cur);
}
if(tmp->get_key() != out->get_key()) {
out = nullptr;
}
}
What seems to be the problem here, that is causing nodes to not be deleted from the binary search tree.

Related

Binary search tree code giving out of resources error

I was trying to create a binary search tree with insert, search and remove functions but when run, the program throwing an error " Killed exit status 137 -- Out Of Resources --" ,
#include <vector>
using namespace std;
class BST
{
public:
int value;
BST *left;
BST *right;
BST(int val)
{
value = val;
left = nullptr;
right = nullptr;
}
BST& insert(int val)
{
BST *current = this;
while (current != nullptr)
{
if (val < current->value)
{
if (current->left == nullptr)
{
current->left = new BST(val);
break;
}
else
current = current->left;
}
if (val > current->value)
{
if (current->right == nullptr)
{
current->right = new BST(val);
break;
}
else
current = current->right;
}
}
return *this;
}
bool contains(int val)
{
BST *current = this;
while (current != nullptr)
{
if (val < current->value)
{
current = current->left;
}
else if (val > current->value)
{
current = current->right;
}
else if (val == current->value)
return true;
//else if(current ==nullptr)
//return false;
}
return false;
}
BST& remove(int val)
{
BST *current = this;
BST *parent = nullptr;
while (current != nullptr)
{
if (val < current->value)
{
parent = current;
current = current->left;
}
if (val > current->value)
{
parent = current;
current = current->right;
}
if (val == current->value)
{
if (current->left != nullptr && current->right != nullptr)
{
fnd(current->right);
}
else if (parent == nullptr)
{
if (current->left != nullptr)
{
current->value = current->left->value;
current->right = current->left->right;
current->left = current->left->left;
}
else if (current->right != nullptr)
{
current->value = current->right->value;
current->left = current->right->left;
current->right = current->right->right;
}
else
current = nullptr;
}
else if (parent->left == current)
{
if (current->left != nullptr)
{
parent->left = current->left;
}
else
{
parent->left = current->right;
}
}
else if (parent->right == current)
{
if (current->left != nullptr)
{
parent->right = current->left;
}
else
{
parent->right = current->right;
}
}
break;
}
}
return *this;
}
void fnd(BST *current)
{
BST *trav = current;
BST *parent;
while (trav->left != nullptr)
{
parent = trav;
trav = trav->left;
}
current->value = trav->value;
parent->left = nullptr;
}
};

Doubly Linked List fails to add or delete valid entries

I've run it many times. I tried fixing my deleteNode() and addNode(), but it did not work. The output showed me that it failed to add some valid entries in my list, which resulted in failing to delete these valid entries. Someone please help me find the errors... I think either my isEmpty() is wrong or the addNode got messed up.
// Add nodes and makes it work in any cases: backward/forward
bool LinkedList::addNode(int id, string str) {
bool result = false;
if (id >= 0 && !(idExists(id))) {
Node *current = head;
Node *temp = new Node;
temp->data.data = str;
temp->data.id = id;
temp->forward = NULL;
temp->back = NULL;
// Kinds of adding cases
if(head == NULL) { // Check if list is empty
addHead(temp, current);
result = true;
} else {
while(temp->data.id > current->data.id && current->forward != NULL) {
current = current->forward;
}
// Backward
if(current->back == NULL) {
if(temp->data.id > current->data.id) {
if(current->forward == NULL) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
} else {
addHead(temp, current);
}
result = true;
// Forward
}else if(current->forward == NULL) {
if (temp->data.id > current->data.id) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
result = true;
}else {
if(temp->data.id > current->data.id) {
addMiddle(temp, current);
result = true;
}
}
}
}
return result;
}
void LinkedList::addHead(Node *temp, Node *current) {
if (head != NULL){
temp->forward = current;
current->back = temp;
head = temp;
} else {
head = temp;
}
}
void LinkedList::addMiddle(Node *temp, Node *current) {
temp->forward = current;
temp->back = current->back;
current->back->forward = temp;
current->back = temp;
}
void LinkedList::addTail(Node *temp, Node *current) {
current->forward = temp;
temp->back = current;
}
// Delete list
bool LinkedList::deleteNode(int id){
bool result = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id && current->forward == NULL) {
if (current->back == NULL) { // Delete head
delete current;
head = NULL;
} else { // delete tail
deleteTail(current);
}
result = true;
} else if (current->data.id == id) {
if (current->back == NULL)
deleteHead(current);
else // delete middle
deleteMiddle(current);
result = true;
}
}
return result;
}
// Helper delete functions
void LinkedList::deleteHead(Node *current) {
head = current->forward;
head->back = NULL;
delete current;
}
void LinkedList::deleteMiddle(Node *current) {
current->back->forward = current->forward;
current->forward->back = current->back;
delete current;
}
void LinkedList::deleteTail(Node *current) {
current->back->forward = NULL;
delete current;
}
bool LinkedList::getNode(int id, Data *data) {
bool didGetNode = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
data->id = current->data.id;
data->data = current->data.data;
didGetNode = true;
}
return didGetNode;
}
// Check whether or not the id exists
bool LinkedList::idExists(int id){
bool exists = false;
if (head != NULL){
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id) {
exists = true;
}
}
return exists;
}
You probably want to be passing a pointer to a pointer (**) or a pointer to a reference (*&) in functions where you are wanting to make a change to what the address of the node is containing. I hope that this helps you visualize it.
For example:
struct Node { };
void setNull1(Node* temp)
{
temp = nullptr;
}
void setNull2(Node** temp)
{
(*temp) = nullptr;
}
void setNull3(Node*& temp)
{
temp = nullptr;
}
int main()
{
Node* tmp = new Node;
setNull1(tmp);
if (tmp == nullptr)
{
cout << "NULLPTR";
} // tmp is not nullptr
Node* tmp1 = new Node;
setNull2(&tmp1);
if (tmp1 == nullptr)
{
cout << "NULLPTR";
} // tmp1 is nullptr
Node* tmp2 = new Node;
setNull3(tmp2);
if (tmp2 == nullptr)
{
cout << "NULLPTR";
} // tmp2 is nullptr
}
You should also consider writing nullptr instead of NULL.

Error when Deleting Node from BST

This genuinely has me stumped. I have a binary search tree of citys that is ordered by the city name. A city also contains the population and GPS coordinates. I want to be able to remove nodes from the tree by City name or city coordinates. I have the delete by name working fine but the GPS coordinates does not work.
When I remove a node by GPS I get a stack-overflow when I try to print the binary tree. Below is some of my code. I cannot understand how it will work fine if I delete by name but not if I delete by coordinates as I am using the same delete method.
The exact error I get is "Unhandled exception at 0x013214D6 in EXE: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00152FFC)." This occurs in my print function after I delete by coordinates but not if I delete by name.
bool BinaryTree::DeleteByName(string city)
{
if (GetRoot() != NULL)
{
return (DeleteByName(GetRoot(), city));
}
return false;
}
TreeNode* BinaryTree::DeleteByName(TreeNode *node, string city)
{
if (node == NULL)
{
return node;
}
else if (city < node->Data.name)
{
node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
node->Right = DeleteByName(node->Right, city);
}
else
{
if (node->Left == NULL && node->Right == NULL)
{
delete node;
node = NULL;
}
else if (node->Left == NULL)
{
TreeNode* temp = node;
node = node->Right;
delete temp;
}
else if (node->Right == NULL)
{
TreeNode* temp = node;
node = node->Left;
delete temp;
}
else
{
cout << "Else";
TreeNode* temp = MinPtr(node->Right);
node->Data = temp->Data;
node->Right = DeleteByName(node->Right, temp->Data.name);
}
}
return node;
}
bool BinaryTree::DeleteByCoord(pair<double, double> coords)
{
if (GetRoot() == NULL)
{
return false;
}
else
{
return DeleteByCoord(GetRoot(), coords);
}
}
bool BinaryTree::DeleteByCoord(TreeNode* node, pair<double, double> coords)
{
bool result;
if (node == NULL)
{
return false;
}
else
{
if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
return (DeleteByName(node, node->Data.name));
}
result = DeleteByCoord(node->Left, coords);
if (result == true)
{
return result;
}
return DeleteByCoord(node->Right, coords);
}
}
void BinaryTree::Insert(City city)
{
TreeNode* temp = new TreeNode(city);
if (GetRoot() == NULL)
{
root = temp;
}
else
{
Insert(temp, GetRoot());
}
}
void BinaryTree::Insert(TreeNode* toAdd, TreeNode* addHere)
{
if (toAdd->Data < addHere->Data)
{
if (addHere->Left != NULL)
{
Insert(toAdd, addHere->Left);
}
else
{
addHere->Left = toAdd;
}
}
else if (toAdd->Data > addHere->Data)
{
if (addHere->Right != NULL)
{
Insert(toAdd, addHere->Right);
}
else
{
addHere->Right = toAdd;
}
}
}
void BinaryTree::InOrderTraversal(TreeNode* node)
{
if (node != NULL)
{
InOrderTraversal(node->Left);
cout << node->Data << endl;
InOrderTraversal(node->Right);
}
}
void BinaryTree::InOrderTraversal()
{
InOrderTraversal(GetRoot());
}
TreeNode* BinaryTree::GetRoot()
{
return root;
}
TreeNode* BinaryTree::MinPtr(TreeNode* node)
{
while (node->Left != NULL)
{
node = node->Left;
}
return node;
}
When you delete the node you also need to update parent pointer that points to deleted node. Pay attention here:
when you call DeleteByName directly it searches required node and returns NULL pointer which automatically set to parent node pointer:
else if (city < node->Data.name)
{
node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
node->Right = DeleteByName(node->Right, city);
}
but when you call DeleteByName from coordinates method you do not reset parent's Left/Right pointers:
if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
return (DeleteByName(node, node->Data.name));
}
in its turn as DeleteByName already receives required node, it does not perform recursive call and does not reset parent's pointers either:
else
{
if (node->Left == NULL && node->Right == NULL)
{
delete node;
node = NULL;
}
//... same here
}
NOTE: There are many more problems in your code. Some that strike the eye:
DeleteByName returns pointer, but DeleteByCoord returns bool, you use pointer as a boolean type in DeleteByCoord
Avoid to compare doubles directly, the comparison result can be wrong. See the question and explanation for the details.

BST node removing - implementing pseudocode

I've got a non-recursive pseudocode for deleting a node (without 2 children case at the moment), which I have to implement. Everything seems to be OK, except the situation when I want to delete a root.
The pseudocode:
delete(root, key)
{
parent = NULL;
p = root; //p - node to delete
while( (p != NULL) && (key != p->data) )
{
parent = p;
if( p->data < key ) p = p->right;
else p = p->left;
}
if( p == NULL ) return;
if( (p->right == NULL) && (p->left == NULL) ) // deleted node p is a leaf
{
if(p == root)
{
root = NULL; // deleted leaf is a root
return;
}
if( parent->right == p) parent->right = NULL;
else parent->left = NULL;
return;
}
if( p->right == NULL ) // p node to delete has only left subtree
{
if( parent->right == p ) parent->right = p->left;
else parent->left = p->left;
return;
}
if( p->left == NULL ) // p node to delete has only right subtree
{
if( parent->right == p ) parent->right = p->right;
else parent->left = p->right;
return;
}
}
And here is my implementation:
struct BstNode
{
int data;
BstNode *left, *right;
};
void Remove(BstNode **root, int key)
{
BstNode **parent, ***p;
parent=NULL;
p=&root;
while((**p!=NULL) && (key!=(**p)->data))
{
parent=&(**p);
if((**p)->data < key) *p=&(**p)->right;
else *p=&(**p)->left;
}
if((**p)==NULL)
{
cout << "no such element! " <<endl;
return;
}
if(((**p)->right)==NULL && (**p)->left==NULL)
{
if((**p)==*root)
{
*root=NULL;
return;
}
if((*parent)->right==(**p))
(*parent)->right = NULL;
else (*parent)->left = NULL;
return;
}
if(((**p)->right)==NULL )
{
if((*parent)->right== (**p))
(*parent)->right = (**p)->left;
else
(*parent)->left = (**p)->left;
return;
}
if(((**p)->left)==NULL )
{
if((*parent)->right==(**p))
(*parent)->right = (**p)->right;
else
(*parent)->left = (**p)->right;
return;
}
}
int main()
{
BstNode* root = NULL;
Insert(&root,2);
/* ... */
Remove(&root,2);
}
I believe that there's something wrong with "parent", because root has no parent. However, I have no idea how to find a way round this problem.

Removing a Node in a BST

I am having trouble getting my remove300 and removeNode300 function working correctly when I remove the root of the tree. (In my case 8). Everything works right(compiling wise), but when I call me inView function, which displays the numbers in the binary tree in ascending order, it takes that 8 out and just puts the highest number in 8's place.
For example:
I insert these numbers in this order, 8,4,12,2,6,10,14,20 and call me remove function to remove 8. I get this output 2,4,5,20,10,12,14. I want it to be 2,4,6,10,12,14,20.
If I can get some help on this on why this process isn't working please let me know. Also let me know if I have to add anything to this post inorder to help you.
Struct definition:
typedef float Element300;
struct TreeNode300;
typedef TreeNode300 * TreePtr300;
struct TreeNode300
{
Element300 element;
TreePtr300 left;
TreePtr300 right;
};
Remove Function:
void BST300::remove300(const Element300 element, TreePtr300 & root)
{
if(root == NULL)
{
cerr << "Error: Remove Failed!" << endl;
}
else if(element == root->element )
{
removeNode300(root);
}
else if(element < root->element)
{
remove300(element, root->left);
}
else
{
remove300(element, root->right);
}
return;
}
Remove Node function:
void BST300::removeNode300(TreePtr300 & root)
{
TreePtr300 tempPointer = NULL;
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
}
else if(root->right == NULL)
{
tempPointer = root;
root = root->left;
tempPointer->left = NULL;
delete tempPointer;
}
else if(root->left == NULL)
{
tempPointer = root;
root = root->right;
tempPointer->right = NULL;
delete tempPointer;
}
else
{
findMaxNode300(root->right, tempPointer);
root->element = tempPointer->element;
delete tempPointer;
}
tempPointer = NULL;
return;
}
find Maximum value function:
void BST300::findMaxNode300(TreePtr300 & root, TreePtr300 & tempPointer)
{
if(root->right == NULL)
{
tempPointer = root;
root = root->left;
tempPointer->left = NULL;
}
else
{
findMaxNode300(root->right, tempPointer);
}
return;
}