BST remove/delete node - root - c++

I got a problem when I delete root node for example if I add to tree 2, 1, 3 and remove 2 (root) something goes wrong when I want to see my tree in preorder and program fails.
Could You explain what's going wrong?
#include <iostream>
#include <string>
using namespace std;
struct BST {
int data;
BST* left;
BST* right;
};
BST* GetNewNode (int data)
{
BST* newNode = new BST ();
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
//******************************BST******************************************************
BST * insertBST (BST * root, int data);
BST * search (BST* root , int data);
BST* FindMin(BST* root);
BST* Delete (BST* root, int data);
BST* DeleteAll(BST* root);
void Inorder(BST *root);
void Preorder(BST *root);
void Postorder(BST *root);
//****************************MAIN***********************************
int main()
{
BST* root = NULL;
string menu= " ";
int f ;
while(menu!="k")
{
cout<<"Chose function (i, r, in ,pre, post, del, f)"<<endl
<<"Want to quit tap k"<<endl;
cin>>menu;
if(menu== "i" )
{
cout<<"If you want to end inserting write 0"<<endl;
cin>>f;
while(f)
{
root = insertBST (root,f );
cin>>f;
}
}
else if(menu == "r" )
{
cout<<"Insert data of node to delete"<<endl;
cin>>f;
Delete(root , f);
}
else if(menu == "in")
Inorder (root);
else if(menu == "pre")
Preorder (root);
else if(menu == "post")
Postorder (root);
else if(menu == "del")
root = DeleteAll(root);
else if(menu == "find")
{
cin>> f;
search(root , f);
}
}
DeleteAll (root);
return 0;
}
///---------------------------------------
BST* insertBST (BST* root, int data)
{
if (root == NULL)
{
root = GetNewNode (data);
}
else if (data <= root->data)
{
root->left = insertBST (root->left, data);
}
else
{
root->right = insertBST (root->right, data);
}
return root;
}
BST* search (BST* root , int data)
{
if (root == NULL) {cout <<"Not found "<<endl; return NULL;}
else if (root->data == data){ cout<<"Found "<<root->data <<endl ;return root;}
else if (data<= root->data) return search (root->left, data);
else return search (root->right, data);
}
BST* Delete (BST* root, int data)
{
if(root == NULL) return root;
else if(data < root->data) root->left = Delete(root->left,data);
else if(data > root->data) root->right = Delete(root->right, data);
else
{
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
} else if(root->left == NULL)
{
struct BST *temp = root;
root = root->right;
delete temp;
} else if(root->right == NULL)
{
struct BST *temp = root;
root = root->left;
delete temp;
} else{
struct BST *temp = FindMin(root->right);
root->data = temp->data;
root->right = Delete(root->right, temp->data);
}
}
return root;
}
void Inorder(BST *root)
{
if(root == NULL) return;
Inorder(root->left);
cout<<root->data<<" ";
Inorder(root->right);
}
void Preorder(BST *root)
{
if (root != NULL)
{
cout<< root->data<<" ";
Preorder (root->left);
Preorder (root->right);
}
else if (root == NULL)
return;
}
void Postorder(BST *root)
{
if (root == NULL)
return;
Postorder (root->left);
Postorder (root->right);
cout<< root->data<<" ";
}
BST* FindMin(BST* root)
{
while(root->left != NULL) root = root->left;
return root;
}
BST* DeleteAll(BST* root)
{
if (root!=NULL)
{
DeleteAll(root->left);
DeleteAll(root->right);
delete(root);
root = NULL;
}
return root;
}

What you are doing is called inorder. below you can check preorder
Preorder:
do stuff with the node // pre means before
recurse left
recurse right
void Preorder(BST *root)
{
if (root == NULL)
return;
cout<< root->data<<" ";
Preorder (root->left);
Preorder (root->right);
}

Related

Deleting a node in a binary search tree

I was implementing binary search tree and also inputting values in to the tree and traversing using inorder traversal. Every function of my class works except deletion, deletion does work at all. Moreover, I would appreciate if someone explains to me why we return values for deletion?
#include <iostream>
using namespace std;
class node {
public:
int key;
node* right;
node* left;
node(int val)
{
key = val;
right = NULL;
left = NULL;
}
};
class BinarySearchTree{
public:
node* root = NULL;
node* insert(node* root, int val) {
if (root == NULL) {
return new node(val);}
else if (val > root->key) {
root->right = insert(root->right, val);
}
else if (val < root->key) {
root->left = insert(root->left, val);
}
return root;}
void inorder(node* root) {
if (root == NULL)
return;
inorder(root->left);
cout << "our node is that " << root->key << endl;
inorder(root->right);
}
int minimumm(node* root) {
node* current = root;
while (current->left != NULL) {
current = current->left;
}
return (current->key);
}
node* deletenode(node* root, int val) {
if (root == NULL) {
return root;
}
else if (val > root->key) {
deletenode(root->right, val);
}
else if (val < root->key) {
deletenode(root->left, val);}
else {
if (root->right == NULL && root->left == NULL) {
delete(root);
return NULL;
}
else if (root->right == NULL) {
node* temp = root->left;
delete(root);
return temp;
}
else if (root->left == NULL) {
node* temp = root->right;
delete(root);
return temp;
}
else {
int temp = minimumm(root->right);
deletenode(root->right, temp);
return root;
}
}
}
};
int main() {
BinarySearchTree bst;
bst.root = bst.insert(bst.root, 100);
bst.root = bst.insert(bst.root, 19);
bst.root = bst.insert(bst.root, 47);
bst.root = bst.insert(bst.root, 3);
bst.root = bst.insert(bst.root, 111);
bst.root = bst.insert(bst.root, 78);
bst.inorder(bst.root);
bst.root = bst.deletenode(bst.root, 78);
bst.root = bst.deletenode(bst.root, 71);
bst.inorder(bst.root);
}
I tried to delete 78 and 71 using deletion class but it didn't work at all

How to delete root node in BST when it has only one child?

#include <iostream>
using namespace std;
class BST {
int data;
BST *left, *right;
public:
BST();
BST(int);
BST* Insert(BST*, int);
void Delete(BST*, BST*, int);
void Inorder(BST*);
};
BST::BST():data(0), left(NULL), right(NULL) {}
BST::BST(int value):BST() {
data = value;
}
BST* BST::Insert(BST *root, int value) {
if(!root) {
return new BST(value);
}
if(value > root->data) {
root->right = Insert(root->right, value);
} else {
root->left = Insert(root->left, value);
}
return root;
}
void BST::Delete(BST *parent, BST *root, int value) {
if(!root) {
return;
}
if(root->data == value) {
if(!root->left && !root->right) {
if(parent) {
if (parent->left == root) {
parent->left = NULL;
}
else {
parent->right = NULL;
}
}
free(root);
return;
}
if(!root->left || !root->right) {
BST *child = root->left ? root->left : root->right;
if(parent) {
if (root == parent->left) {
parent->left = child;
}
else {
parent->right = child;
}
free(root);
} else {
// what do i have to do here ?
}
return;
}
BST *inorderSuccessor = root->right;
parent = root;
while (inorderSuccessor->left) {
parent = inorderSuccessor;
inorderSuccessor = inorderSuccessor->left;
}
root->data = inorderSuccessor->data;
Delete(parent, inorderSuccessor, inorderSuccessor->data);
}
if(value > root->data) {
Delete(root, root->right, value);
} else {
Delete(root, root->left, value);
}
}
void BST::Inorder(BST *root) {
if(!root) {
return;
}
Inorder(root->left);
cout << root->data << " ";
Inorder(root->right);
}
int main() {
BST bst, *root = NULL;
root = bst.Insert(root, 4);
bst.Insert(root, 2);
// bst.Insert(root, 5);
bst.Insert(root, 1);
bst.Insert(root, 3);
bst.Delete(NULL, root, 4);
bst.Inorder(root);
return 0;
}
When i do free(root) whole of tree gets deleted.
I have done almost everything I know but it just doesn't run correctly.
I am keeping track of parent node in the function itself.
I am using recursion to do that. I can tell a node is root of tree if parent is null.
Everything else is working fine. I have checked all the other cases.

ASAN: heap-use-after-free when flattening a binary tree to a linked list

This is a Leetcode question, Flatten Binary Tree to Linked List.
My solution is very straightforward. For a node root, push root->right onto a stack. Set the root->left to the root->right and set root->left to NULL.
I get a runtime error:
AddressSanitizer: heap-use-after-free on address 0x603000000108 at pc
0x00000046bf70 bp 0x7ffc5d6c5f70 sp 0x7ffc5d6c5f68
What is causing the error?
Here's my code:
class Solution {
public:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){
if(root == NULL){
if(s.empty()) return;
else{
TreeNode* newroot = s.top();
s.pop();
pre->right = newroot;
flat_tree(pre, newroot,s);
}
}else{
if(root->left == NULL) {
flat_tree(root, root->right, s);
}else if(root->right == NULL){
root->right = root->left;
flat_tree(root, root->right, s);
}else{
TreeNode* right = root->right;
root->right = root->left;
s.push(right);
flat_tree(root, root->right, s);
}
}
}
void flatten(TreeNode* root) {
stack<TreeNode*> s;
flat_tree(NULL ,root,s);
}
};
This is very close. Left node pointers need to be nulled out after their child is moved over to the right side of the root, preventing the double free heap corruption which occurs when the test suite follows two pointers to the same memory location.
Here's the working code:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){
if(root == NULL){
if(s.empty()) return;
else{
TreeNode* newroot = s.top();
s.pop();
pre->right = newroot;
flat_tree(pre, newroot,s);
}
}else{
if(root->left == NULL) {
flat_tree(root, root->right, s);
}else if(root->right == NULL){
root->right = root->left;
root->left = NULL; /* set the left pointer to null */
flat_tree(root, root->right, s);
}else{
TreeNode* right = root->right;
root->right = root->left;
root->left = NULL; /* do the same here */
s.push(right);
flat_tree(root, root->right, s);
}
}
}
I also recommend reorganizing branches to avoid duplicated logic:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s) {
if (root) {
if (root->right) {
s.push(root->right);
}
root->right = root->left;
root->left = NULL;
flat_tree(root, root->right, s);
}
else if (!s.empty()) {
pre->right = s.top();
s.pop();
flat_tree(pre, pre->right, s);
}
}

Binary Search Tree implementation giving segmentation fault

This is the c++ code to implement binary search tree where program gets seg. fault:
#include<iostream>
#include<cstdlib>
#include<stack>
struct BSTNode
{
int info;
struct BSTNode *left, *right;
};
class BST
{
private:
//BSTNode *root;
public:
void rpreorder(BSTNode*);
void rinorder(BSTNode*);
void rpostorder(BSTNode*);
BSTNode * search(BSTNode*, int);
BSTNode* insert(BSTNode*, int);
};
void BST:: rpreorder(BSTNode *root)
{
if(root == NULL)
return ;
std::cout<<" "<<root->info;
rpreorder(root->left);
rpreorder(root->right);
}
void BST:: rinorder(BSTNode *root)
{
if(root = NULL)
return ;
rinorder(root->left);
std::cout<<" "<<root->info;
rinorder(root->right);
}
void BST:: rpostorder(BSTNode *root)
{
if(root == NULL)
return ;
rpostorder(root->left);
rpostorder(root->right);
std::cout<<" "<<root->info;
}
BSTNode * BST:: search(BSTNode* root, int data)
{
if(root == NULL)
return root;
if(data < root->info)
return search(root->left, data);
else if(data > root->info)
return search(root->right, data);
return root;
}
BSTNode* BST:: insert(BSTNode *root, int data)
{
BSTNode* parent;
BSTNode* newNode = new BSTNode;
newNode->info = data;
newNode->right = NULL;
newNode->left = NULL;
if(root == NULL)
root = newNode;
else
{
parent = root;
while(parent != NULL)
{
if(data < parent->info)
{
if(parent->left == NULL)
parent->left = newNode;
parent = parent->left;
}
else if(data > parent->info)
{
if(parent->right == NULL)
parent->right = newNode;
parent = parent->right;
}
}
}
return root;
}
int main()
{
int choice, value;
BST obj;
BSTNode *root = NULL;
while(1)
{
std::cout<<"\n Enter the choice : \n 1. To insert \n 2. To search \n 3. recursive preorder \n 4. recursive inorder \n 5. recursive \
postorder \n 6. EXIT \n : ";
std::cin>>choice;
switch(choice)
{
case 1:
std::cout<<"\n Enter element to insert : ";
std::cin>>value;
root = obj.insert(root, value);
break;
case 2:
std::cout<<"\n Enter the element to search : ";
std::cin>>value;
{
BSTNode* temp;
temp = obj.search(root, value);
if(temp == NULL)
std::cout<<"\n Element not found "<<std::endl;
else
std::cout<<"\n The element found ";
}
break;
case 3:
obj.rpreorder(root);
break;
case 4:
obj.rinorder(root);
break;
case 5:
obj.rpostorder(root);
break;
case 6:
exit(0);
}
}
return 0;
}
The seg. fault is coming in this segment of above code :
void BST:: rinorder(BSTNode *root)
{
if(root = NULL)
return ;
rinorder(root->left); // <- this line gives seg. fault
std::cout<<" "<<root->info;
rinorder(root->right);
}
There is one more problem to this code :
After inserting only one element in BST I can't insert more elements into the BST.

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;
}