delete element BST - c++

When I delete 25 from BT than it works perfectly.
But when I want to delete another number like 17,
it deletes 17 with some other number are deleted from BT.
#include<iostream>
using namespace std;
struct node
{
int data;
node *left;
node *right;
};
node *root = NULL;
node* createnode(int data)
{
node *t = new node();
t->data = data;
t->left = NULL;
t->right = NULL;
return t;
}
node* min(node*);
node* insert(node *root, int data)
{
if (root == NULL)
{
root = createnode(data);
return root;
}
else{
node *t = root;
if (data <= t->data)
t->left = insert(t->left, data);
else{
t->right = insert(t->right, data);
}
}
}
node* print(node *root)
{
if (root == NULL)
{
return root;
}
else{
cout << root->data << " ";
print(root->left);
print(root->right);
}
return root;
}
node* deleten(node *root, int data)
{
if (root == NULL)
return root;
else{
if (data<root->data)
root->left = deleten(root->left, data);
if (data>root->data)
root->right = deleten(root->right, data);
else{
if (root->left == NULL && root->right == NULL)
{
node *t = root;
root = NULL;
delete t;
}
else if (root->left == NULL)
{
node *t = root;
root = root->right;
delete t;
}
else if (root->right == NULL)
{
node *t = root;
root = root->left;
delete t;
}
else{
node *t = min(root->right);
root->data = t->data;
root->right = deleten(root->right, t->data);
}
}
return root;
}
}
node* min(node *root)
{
if (root == NULL)
return root;
else{
if (root->left != NULL)
min(root->left);
else{
return root;
}
}
}
int main()
{
root = insert(root, 15);
root = insert(root, 10);
root = insert(root, 8);
root = insert(root, 12);
root = insert(root, 11);
root = insert(root, 20);
root = insert(root, 23);
root = insert(root, 17);
root = insert(root, 25);
root = print(root);
cout << endl;
root = deleten(root, 17);
root = print(root);
}
case 1:
before deletion : 15 10 8 12 11 20 17 23 25
after deletion : 15 10 8 12 11 23 25 // root=deleten(root,17);
expectation : 15 10 8 12 11 20 23 25
case 2:
before deletion : 15 10 8 12 11 20 17 23 25
after deletion : 15 10 8 12 11 20 17 23 // root=deleten(root,25);
expectation : 15 10 8 12 11 20 17 23
case 3:
before deletion : 15 10 8 12 11 20 17 23 25
after deletion : 17 12 11 23 25 // root= deleten(root,8);
expectation : 15 10 12 11 20 17 23 25

The error is here:
if (data<root->data)
root->left = deleten(root->left, data);
if (data>root->data)
root->right = deleten(root->right, data);
else{
//...
}
If data is less than root->data, it will delete the left side of the tree, and the node, since you are using if not else if to test for the right.
The answer is simple, change to an else if instead:
if (data<root->data)
root->left = deleten(root->left, data);
else if (data>root->data)
root->right = deleten(root->right, data);
else{
//...
}

Related

Error trying to remove duplicate element from sorted Linked List

Why is my code giving a segmentation fault?
The code runs perfectly for some test cases, but after a few it starts giving a segmentation fault
Node *remove(Node *curr){
Node *temp=curr;
while(curr->data==curr->next->data){
curr=curr->next;
}
temp->next=curr->next;
delete(curr);
return temp->next;
}
//Function to remove duplicates from sorted linked list.
Node *removeDuplicates(Node *head)
{
// your code goes here
Node *curr=head;
while(curr->next!=NULL){
if(curr->data == curr->next->data){
curr=remove(curr);
}
else{
curr=curr->next;
}
}
return head;
}
You seem to be crossing purpose with these functions, and you're note retaining your proper target for your potentially updated duplicate consolidation.
I'm gonna change the name to removeNode for several reasons, one of which is to avoid confusing it with std::remove that wouldn't be a problem if you hadn't inadvisably pulled the entire std namespace into play) The function should delete a (singular) node and return the node after (if there is one). It isn't a particularly helpful function to be honest, since all it should do is this:
Node *removeNode(Node *curr)
{
if (curr)
{
Node *tmp = curr;
curr = curr->next;
delete tmp;
}
return curr;
}
Pretty boring, but it gets the job done. Now, we can use that to remove duplicates by way of an efficient pointer-to-pointer approach:
Node *removeDuplicates(Node *head)
{
Node **pp = &head;
while (*pp && (*pp)->next)
{
if ((*pp)->data == (*pp)->next->data)
{
*pp = removeNode(*pp);
}
else
{
pp = &(*pp)->next;
}
}
return head;
}
And that's it. A test jig that exhibits how this works is below:
#include <iostream>
#include <random>
struct Node
{
int data;
Node *next;
};
void print(const Node *p, std::ostream& outp = std::cout)
{
if (p)
{
for (; p; p=p->next)
{
outp << p->data << ' ';
}
outp << '\n';
}
}
Node *insertSorted(Node *head, int value)
{
Node **pp = &head;
while (*pp && (*pp)->data < value)
pp = &(*pp)->next;
Node *p = new Node;
p->data = value;
p->next = *pp;
*pp = p;
return head;
}
Node *removeNode(Node *curr)
{
if (curr)
{
Node *tmp = curr;
curr = curr->next;
delete tmp;
}
return curr;
}
Node *removeDuplicates(Node *head)
{
Node **pp = &head;
while (*pp && (*pp)->next)
{
if ((*pp)->data == (*pp)->next->data)
{
*pp = removeNode(*pp);
}
else
{
pp = &(*pp)->next;
}
}
return head;
}
void removeAll(Node *head)
{
while (head)
{
Node *tmp = head;
head = head->next;
delete tmp;
}
}
int main()
{
std::mt19937 rng{ std::random_device{}() };
std::uniform_int_distribution<> dist(1,50);
Node *head = nullptr;
for (int i=0; i<30; ++i)
head = insertSorted(head, dist(rng));
print(head);
head = removeDuplicates(head);
print(head);
removeAll(head);
}
Output (varies)
2 4 4 4 6 7 7 8 18 18 19 23 26 27 29 31 32 33 34 34 36 36 37 37 38 40 43 44 46 49
2 4 6 7 8 18 19 23 26 27 29 31 32 33 34 36 37 38 40 43 44 46 49

Height of Skewed Binary Search Tree

I have implemented the code as follows, In this I have made two functions to calculate the height of binary search tree using recursion and without recursion.
#include <iostream>
#include <list>
using namespace std;
struct node
{
int key;
struct node *left, *right;
};
struct node *newNode(int item)
{
struct node *temp = new node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
printf("%d ", root->key);
inorder(root->right);
}
}
struct node *insert(struct node *node, int key)
{
if (node == NULL)
return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
return node;
}
int heightRecursive(struct node *node)
{
if (node == NULL)
return -1;
else
{
int lDepth = heightRecursive(node->left);
int rDepth = heightRecursive(node->right);
if (lDepth > rDepth)
return (lDepth + 1);
else
return (rDepth + 1);
}
}
int heightNonRecursive(node* root)
{
if (root == NULL) {
return 0;
}
list<node*> queue;
queue.push_back(root);
node* front = NULL;
int height = 0;
while (!queue.empty())
{
int size = queue.size();
while (size--)
{
front = queue.front();
queue.pop_front();
if (front->left) {
queue.push_back(front->left);
}
if (front->right) {
queue.push_back(front->right);
}
}
height++;
}
return height;
}
int main()
{
struct node *root = NULL;
root = insert(root, 10);
insert(root, 20);
insert(root, 30);
insert(root, 40);
insert(root, 50);
insert(root, 60);
insert(root, 70);
insert(root, 75);
insert(root, 80);
inorder(root);
int h = heightRecursive(root);
cout << "\n\nHeight of tree using recursive function: " << heightRecursive(root);
cout << "\nHeight of tree using non-recursive function: " << heightNonRecursive(root);
return 0;
}
I have implemented a skewed binary tree like 10->20->30->40->50->60->70->75->80, but in the heightNonRecursive() function, I am getting the height of this binary search tree as 9. Please help where I am doing mistake.
Output of above code:
10 20 30 40 50 60 70 75 80
Height of tree using recursive function: 8
Height of tree using non-recursive function: 9
You have 9 different numbers in increasing order, in unbalanced tree, so the height should be 8, which is correct with recursive function.
10
20
30
40
50
60
70
75
80
With non-recursive function, you just have to start with height = -1;, it should return 0 if there is only one item in the tree.
int heightNonRecursive(node* root)
{
if (root == NULL)
return 0;
list<node*> queue;
queue.push_back(root);
node* front = NULL;
int height = -1; //<-start at -1
while (!queue.empty())
{
int size = queue.size();
while (size--)
{
front = queue.front();
queue.pop_front();
if (front->left)
queue.push_back(front->left);
if (front->right)
queue.push_back(front->right);
}
height++;
}
return height;
}

Why my code for deleting a node in BST instead of deletion is assigning a new value like 0 or random value to node to be deleted?

Node* search(Node* &root, int data) {
if (root == NULL) {
cout << "key not found\n";
return NULL;
}
if (root -> key == data)
return root;
else if(root-> key > data)
return search(root -> left, data);
else
return search(root -> right,data);
}
Node* findMinVal(Node* &root){
Node* current = root;
while (current -> left != NULL)
current = current -> left;
return current;
}
void deleteNode(Node* &root, int key) {
if (root == NULL)
return;
Node* node = search(root, key);
if (node -> left == NULL) {
Node* temp = node;
node = node -> right;
free(temp);
}
else if (node -> right == NULL) {
Node* temp;
node = node -> left;
free(temp);
}
else {
Node* temp = findMinVal(node -> right);
node -> key = temp -> key;
free(temp);
}
}
example tree:
Inorder traversal of the given tree:
20 30 40 50 60 70 80
output and commands :
Delete 20
Inorder traversal of the modified tree
0 30 40 50 60 70 80

BST insertion,deletion,search

I was solving a problem and it stated:
Write a program that processes the following queries on a Binary Search Tree:
i x: Insert x in the BST
d x: Delete x from the BST
Input format
Line 1 contains an integer Q, the number of queries
The next Q lines are of the form i x or d x
Output format
For each query, print the position of x in the BST
If the position of a node is p, the positions of its left and right children are 2*p and 2*p+1 respectively
Position of the root node is 1
Question's link
11 //Queries
i 15 //i=insert; d=delete
i 9
i 25
i 8
i 13
i 18
i 19
i 7
i 11
d 9
i 14
Everything is working fine until I delete node 9. then the position of node 14 is coming out to be 5. see the diagram:Initially,
15
/ \
9 25
/ \ /
8 13 18
/ / \
7 11 19
After deleting 9;
15
/ \
11 25
/ \ /
8 13 18
/ \
7 19
After inserting 14
15
/ \
11 25
/ \ /
8 14 18
/ / \
7 13 19
Correct format should be
15
/ \
11 25
/ \ /
8 13 18
/ \ \
7 14 19
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll position=1;
struct BSTNode
{
int data;
BSTNode *left,*right;
};
BSTNode *getNewNode(int data)
{
BSTNode *newNode = new BSTNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode; //returns address of new node
}
BSTNode* insert(BSTNode *root,int data)
{
if(root==NULL){
root = getNewNode(data);
}
else if(data<root->data)
{
root->left = insert(root->left,data);
}
else if(data>root->data)
{
root->right = insert(root->right,data);
}
return root;
}
BSTNode *findMin(BSTNode *root)
{
if(root->left ==NULL)
{
return root;
}
else
findMin(root->left);
}
bool search(BSTNode *root,int data)
{
if(root == NULL)
{
return 0;
}
if(data<root->data)
{
position=2*position;
search(root->left,data);
}
else if(data>root->data)
{
position=2*position+1;
search(root->right,data);
}
else
{
cout<<"Found";
return 1;
}
}
BSTNode* delet(BSTNode* root,int data)
{
if(root == NULL)
{
return 0;
}
else if(data<root->data)
{
root->left = delet(root->left,data);
}
else if(data>root->data)
{
root->right = delet(root->right,data);
}
else //Found
{
//CASE 1:No child
if(root->left == root->right ==NULL)
{
delete root;
root = NULL;
}
//CASE2: One child
else if(root->left == NULL)
{
BSTNode *temp= root;
root = root->right;
delete temp;
}
else if(root->right == NULL)
{
BSTNode *temp=root;
root= root->left;
delete temp;
}
//CASE 3: TWO CHILD
else
{
BSTNode *temp = findMin(root->right);
root->data = temp->data;
root->right = delet(root->right,root->data);
}
return root;
}
}
int main()
{
BSTNode* root = NULL; //rootptr- pointer to node
//tree is empty
int n,input,data,del;
char c;
cin>>n;
while(n--)
{
cin>>c;
cin>>input;
if(c=='i')
{
root = insert(root,input);
search(root,input);
}
if(c=='d')
{
search(root,input);
delet(root,input);
}
cout<<position<<endl;
position=1;
}
return 0;
}
How is this possible insertion is being done as a leaf node Then?
in the line
Correct format should be
your diagram is wrong. 14 is the right child of 13.
Assume that you want to insert a node is a binary search tree, you need to save the last parent node in the your searching path if the given node is not found. and insert the new node to the last parent node got in the function insert(). The program is not recursive.
here is an example in C.
#include<stdio.h>
#include<stdlib.h>
struct t_Data
{
int m_Info;
};
struct t_Node
{
struct t_Data m_Data;
struct t_Node* m_LeftChild;
struct t_Node* m_RightChild;
};
typedef struct t_Node* t_BinarySortTree;
/* return targetNode or the last node in the path */
int SearchBST(t_BinarySortTree T, int aGivenInfo, struct t_Node* lastParentNode, struct t_Node* *result)
{
if(!T)
{
*result = lastParentNode;
return 0;
}
else if (aGivenInfo == (*T).m_Data.m_Info)
{
*result = T;
return 1;
}
else if(aGivenInfo < (*T).m_Data.m_Info)
{
lastParentNode = T;
return SearchBST((*T).m_LeftChild,aGivenInfo,lastParentNode,result);
}
else
{
lastParentNode = T;
return SearchBST((*T).m_RightChild,aGivenInfo,lastParentNode,result);
}
}
void InsertBST(t_BinarySortTree *T, struct t_Data newData)
{
int status;
struct t_Node* result;
status = SearchBST(*T,newData.m_Info,NULL,&result);
/* condition: fail to search for 'newData' in the binary sort tree */
if (!status)
{
struct t_Node* newNode;
newNode = (struct t_Node*)malloc(sizeof(struct t_Node));
(*newNode).m_Data = newData;
(*newNode).m_LeftChild = NULL;
(*newNode).m_RightChild = NULL;
/* condition: result == NULL */
if (!result)
{
*T = newNode;
}
else if (newData.m_Info < (*result).m_Data.m_Info)
{
(*result).m_LeftChild = newNode;
}
/* condition: newData.m_Info > (*result).m_Data.m_Info */
else
{
(*result).m_RightChild = newNode;
}
}
}
int main(void)
{
t_BinarySortTree aBST;
aBST = NULL;
struct t_Data d1,d2,d3,d4,d5,d6,d7,d8,d9,d10;
d1.m_Info = 62;
d2.m_Info = 88;
d3.m_Info = 58;
d4.m_Info = 47;
d5.m_Info = 35;
d6.m_Info = 73;
d7.m_Info = 51;
d8.m_Info = 99;
d9.m_Info = 37;
d10.m_Info = 93;
InsertBST(&aBST,d1);
InsertBST(&aBST,d2);
InsertBST(&aBST,d3);
InsertBST(&aBST,d4);
InsertBST(&aBST,d5);
InsertBST(&aBST,d6);
InsertBST(&aBST,d7);
InsertBST(&aBST,d8);
InsertBST(&aBST,d9);
InsertBST(&aBST,d10);
}

Binary Tree Traversal - Preorder, Inorder, Postorder

I am trying to get the following output
Preorder : 50 5 20 15 27 42 35 25 55 70 60 80 95 90 75
Inorder : 5 15 20 25 27 35 42 50 55 60 70 75 80 90 95
Postorder: 5 20 15 27 42 35 25 55 70 60 80 95 90 75 50
Instead I am getting this
Preorder : 136161285312597531284813109128551336214133138721362114128146401438414645
Inorder : 531259712848128531285513109133621361613621138721412814133143841464014645
Postorder: 531284812597128551336213109128531362114128138721438414645146401413313616
Here is my code
#include "stdafx.h"
#include<iostream>
using namespace std;
struct Node {
int data;
Node *left;
Node *right;
};
//Preorder Funcation
void Preorder(struct Node *root) {
if (root == NULL) return; // if tree/sub-tree is empty, return and exit
cout << root->data; // Visit
Preorder(root->left); // Move left
Preorder(root->right); // move right
}
//Inorder Funcation
void Inorder(Node *root) {
if (root == NULL) return; // if tree/sub-tree is empty, return and exit
Inorder(root->left); //Move left
cout << root->data; //Visit
Inorder(root->right); // move right
}
//Postorder Funcation
void Postorder(Node *root) {
if (root == NULL) return; // if tree/sub-tree is empty, return and exit
Postorder(root->left); // Move left
Postorder(root->right); // move right
cout << root->data; // Visit
}
// Function to Insert Node in a Binary Search Tree
Node* Insert(Node *root, int data) {
if (root == NULL) {
root = new Node();
root->data = data;
root->left = root->right = NULL;
}
else if (data <= root->data)
root->left = Insert(root->left, data);
else
root->right = Insert(root->right, data);
return root;
}
int main() {
Node *root = NULL;
root = Insert(root, '50');
root = Insert(root, '75');
root = Insert(root, '25');
root = Insert(root, '15');
root = Insert(root, '60');
root = Insert(root, '35');
root = Insert(root, '90');
root = Insert(root, '42');
root = Insert(root, '20');
root = Insert(root, '27');
root = Insert(root, '5');
root = Insert(root, '55');
root = Insert(root, '95');
root = Insert(root, '80');
root = Insert(root, '70');
cout << "Preorder: "; //Diaplay Nodes in Preorder.
Preorder(root);
cout << "\n";
cout << "Inorder: "; //Display Nodes in Inorder
Inorder(root);
cout << "\n";
cout << "Postorder: "; //Display Nodes in Postorder
Postorder(root);
cout << "\n";
return 0;
}