BST - Deleting a Node - c

so I'm trying to solve a problem from log2base2.com involving deleting a node from BST. It works except when trying to delete a node with two children. I know I could simply replace the numbers and then delete the duplicate at the end, but what if my struct has more data than just key? So what am I doing wrong please?
#include<stdio.h>
#include<stdlib.h>
struct node
{
int key;
struct node *left;
struct node *right;
};
int getRightMin(struct node *root)
{
//Write your code here
struct node *temp = root;
while(temp->left!=NULL)
{
temp=temp->left;
}
return temp;
}
struct node *removeNode(struct node *root, int key)
{
//Write your code here
if(root == NULL){return NULL;}
if(key<root->key){root->left = removeNode(root->left, key);}
else if(key>root->key){root->right = removeNode(root->right,key);}
else
{
if(root->left==NULL && root->right==NULL)
{
free(root);
return NULL;
}
else if(root->left)
{
struct node *temp = root->left;
free(root);
return temp;
}
else if(root->right)
{
struct node *temp = root->right;
free(root);
return temp;
}
else
{
struct node *temp = getRightMin(root->right);
temp->left = root->left;
temp->right = root->right;
root = temp;
root->right = removeNode(root->right, temp->key);
}
}
return root;
}
//Don't change the below code
struct node *getNewNode(int val)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->key = val;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
struct node *insert(struct node *root, int val)
{
if(root == NULL)
return getNewNode(val);
if(root->key < val)
root->right = insert(root->right,val);
else if(root->key > val)
root->left = insert(root->left,val);
return root;
}
void inorder(struct node *root)
{
if(root == NULL)
return;
inorder(root->left);
printf("%d ",root->key);
inorder(root->right);
}
int main()
{
struct node *root = NULL;
root = insert(root,100);
root = insert(root,50);
root = insert(root,200);
root = insert(root,150);
root = insert(root,300);
int key;
scanf("%d",&key);
root = removeNode(root,key);
inorder(root);
return 0;
}
TEST CASE 1:
INPUT: 200
EXPECTED OUTPUT: 50 100 150 300
ACTUAL OUTPUT: 50 100 150
TEST CASE 2:
INPUT: 100
EXPECTED OUTPUT: 50 150 200 300
ACTUAL OUTPUT: 50

You have to reorder conditional in removeNode() to:
if(root->left==NULL && root->right==NULL)
{
free(root);
return NULL;
}
else if (root->left && root->right)
{
struct node *temp = getRightMin(root->right);
temp->left = root->left;
temp->right = root->right;
root = temp;
root->right = removeNode(root->right, temp->key);
}
else if(root->left)
{
struct node *temp = root->left;
free(root);
return temp;
}
else // root->right != NULL
{
struct node *temp = root->right;
free(root);
return temp;
}
It looks that (root->left && root->right) case was caught by (root->left) and
reference to root->right was lost.

Related

Why is the key of the left node missing after insertion?

I could not use the Insert_node to insert a node with corresponding key, and I couldn't figure out the problem.
Keys is an array of integers I created earlier.
Here is the code:
Node* Create_node(int x)
{
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = x;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Node* Insert_node(Node** proot, int x)
{
Node* root = *proot;
if(root == NULL)
{
root = Create_node(x);
}
return root;
}
int main()
{
Node* root = Create_node(keys[0]);
Insert_node(&root->left,keys[1]);
printTree(root);
return 0;
}

View AVL tree not giving the correct output

I am working on a school project that involves implementing an AVL Tree with the functions to insert delete and view. But my program didnt give the correct output when viewing the avl tree with preorder traversal.
The variable for avl tree:
typedef struct Node{
int data;
int height;
struct Node *right;
struct Node *left;
}Node;
Here is my insert function with newnode function call:
Node *newNode(int data){
Node *node = (Node*)malloc(sizeof(Node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->height = 1;
return(node);
}
Node *insertNode(Node *node, int data){
if(node == NULL)
return(newNode(data));
if(data < node->data)
node->left = insertNode(node->left, data);
if(data > node->data)
node->right = insertNode(node->right, data);
if(data == node->data){
printf("No duplicate allowed.");
return node;
}
node->height = getHeight(node);
return(balancing(node, data));
}
Delete function with minvaluenode function call:
Node * minValueNode(Node* node){
Node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
Node *deleteNode(Node *root, int data){
if(root == NULL){
printf("Value not found.");
return root;
}
else if ( data < root->data )
root->left = deleteNode(root->left, data);
else if( data > root->data )
root->right = deleteNode(root->right, data);
else if(data == root->data){
if( (root->left == NULL) || (root->right == NULL) ){
Node *temp = root->left ? root->left : root->right;
if (temp == NULL){
temp = root;
root = NULL;
}
else
*root = *temp;
free(temp);
}
else{
Node* temp = minValueNode(root->right);
root->data = temp->data;
root->right = deleteNode(root->right,temp->data);
}
}
if(root == NULL)
return root;
root->height = getHeight(root);
return(balancing(root, data));
}
Balancing function with rotate,getbalancefactor, max, and getheight function calls:
int max(int number1, int number2){
return (number1 > number2) ? number1 : number2;
}
int getHeight(Node* n) {
return max(height(n->left), height(n->right)) + 1;
}
int getBalanceFactor(Node *currentNode){
if(currentNode == NULL)
return 0;
return height(currentNode->left) - height(currentNode->right);
}
Node *rightRotate(Node *currentNode){
Node *temp = currentNode->left;
currentNode->left = temp->right;
temp->right = currentNode;
temp->height = getHeight(temp);
currentNode->height = getHeight(currentNode);
return temp;
}
Node *leftRotate(Node *currentNode){
Node *temp = currentNode->right;
currentNode->right = temp->left;
temp->left = currentNode;
temp->height = getHeight(temp);
currentNode->height = getHeight(currentNode);
return temp;
}
Node *balancing(Node *node, int data){
if(getBalanceFactor(node) >= 2 && data < node->left->data)
return rightRotate(node);
if(getBalanceFactor(node) <= -2 && data > node->right->data)
return leftRotate(node);
if(getBalanceFactor(node) >= 2 && data > node->left->data){
node->left = leftRotate(node->left);
return(rightRotate(node));
}
if(getBalanceFactor(node) <= -2 && data < node->right->data){
node->right = rightRotate(node->right);
return(leftRotate(node));
}
return node;
}
My view function:
//print AVL Tree in preorder traversal
void printAVLTree(Node *root){
if(root != NULL)
{
printf("%d ", root->data);
printAVLTree(root->left);
printAVLTree(root->right);
}
}
I made a test with random insert input:
9 5 10 6 0 11 -1 1 2
The output when calling the view function is:
5 1 0 -1 2 9 6 10 11
The correct output should be:
9 1 0 -1 5 2 6 10 11
Your mistake is that you are updating the height values in the wrong order (top to bottom):
temp->height = getHeight(temp);
currentNode->height = getHeight(currentNode);
After rotation, the lower node is currentNode so you have to update it first.
Otherwise, if you update temp before updating currentNode, temp will use the previous value of currentNode height and will have a wrong height

Deletion of node in Binary Search Tree is throwing error

Experts, this is my code of creation and deletion of nodes in Binary Search Tree. It's working fine for insertion, but throwing segmentation fault (core dumped) when trying to delete a node (on invoking deleteNode( ) function). I don't understand what's actually the problem. Please help! Thank you in advance!
#include <stdio.h>
#include <stdlib.h>
int size = 0;
typedef struct mylist{
int data;
struct mylist *left;
struct mylist *right;
}node;
node *root;
void create_root(node *root){
root = NULL;
}
//Inserting nodes
node* insert(node *root, int val){
node *ptr, *parentptr, *nodeptr;
ptr = (node*)malloc(sizeof(node));
ptr -> data = val;
ptr -> left = NULL;
ptr -> right = NULL;
if(root == NULL)
root = ptr;
else{
parentptr = NULL;
nodeptr = root;
while(nodeptr != NULL){
parentptr=nodeptr;
if(val < nodeptr -> data)
nodeptr = nodeptr -> left;
else
nodeptr = nodeptr -> right;
}
if(val < parentptr -> data)
parentptr -> left = ptr;
else
parentptr -> right = ptr;
}
return root;
}
node* minValueNode(node* root)
{
node* cur = root;
while (cur->left != NULL)
cur = cur->left;
return cur;
}
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
}
if (key < root-> data)
root->left = deleteNode(root->left, key);
else if (key > root-> data)
root->right = deleteNode(root->right, key);
else
{
if (root->left == NULL)
{
node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
node *temp = root->left;
free(root);
return temp;
}
node* temp = minValueNode(root->right); //Inorder successor
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
return root;
}
void main(){
int option, val;
node *ptr;
int flag = 1;
create_root(root);
while(flag != 2){
printf("\nChoose-\n1-Insert\n2-Delete\n3-Exit\n");
scanf("%d", &option);
switch(option){
case 1:{
printf("\nEnter the value of new node\n");
size++;
scanf("%d", &val);
root = insert(root, val);
break;
}
case 2:{
int k;
printf("Enter the value to delete");
scanf("%d",&k);
root=deleteNode(root, k);
size--;
break;
}
case 3:
flag=2;
break;
default:
printf("\nWrong entry\n");
}
}
}
You must either return NULL in the first if() in deleteNode(), or you must put an else before the second if()
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
return NULL; // <== This was missing.
}
...
}
or alternatively (perhaps intended?):
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
}
else if(key < root->data)
...
}
At the moment this falls through to the next if(key < root->data) even when root is null, which causes the segfault.
Also: Use nullptr if you can use C++11.

Deleting a node with 2 children from a binary search tree

I am trying to delete a node having 2 chidren in a binary search tree. However i am facing little problem here. While deleting node(node with data=30) with children (left->data=20,right->data=40), I am replacing the node with its inorder successor (which is node with data=40) and then deleting the inorder successor. After deletion the node's data is successfully replaced (new value being 40) but the inorder successor is not being deleted/freed properly.
Expected Output [inorder traversal]: 20->40->50->60->70->80->
Output[inorder traversal]: 20->40->0->50->60->70->80->
After 40, why is the value 0 appearing?
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *left;
struct Node *right;
};
struct Node* temp = NULL,*temp1 = NULL;
struct Node *newNode(int data)
{
struct Node *node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
struct Node* insert(struct Node* root,int data)
{
if(root == NULL)
{
return newNode(data);
}
if(data < root->data)
root->left = insert(root->left,data);
else
root->right = insert(root->right,data);
}
void inorder(struct Node* root)
{
if(root!=NULL)
{
inorder(root->left);
printf("%d->",root->data);
inorder(root->right);
}
else
{
return;
}
}
/*to find the inorder successor*/
struct Node *minVal(struct Node *root)
{
while(root->left !=NULL)
{
temp = root;
root = root->left;
}
return root;
}
void deleteNode(struct Node *root,int data)
{
if(data < root->data)
{
temp = root;
deleteNode(root->left,data);
}
else if(data > root->data)
{
temp = root;
deleteNode(root->right,data);
}
else if(data == root->data)
{ /*deleting leaf nodes*/
if(root->left == NULL && root->right == NULL)
{
if(temp->left == root)
temp->left = NULL;
else
if(temp->right == root)
temp->right = NULL;
free(root);
root = NULL;
return;
}
/*deleting nodes having single child*/
else if(root->left !=NULL && root->right == NULL)
{
temp1 = root->left;
temp->left = temp1;
free(root);
root = NULL;
}
else if(root->left ==NULL && root->right != NULL)
{
temp1 = root->right;
temp->right = temp1;
free(root);
root = NULL;
}
/*deleting nodes having 2 children*/
else if(root->left !=NULL && root->right !=NULL)
{
struct Node *temp2 = minVal(root->right);
root->data = temp2->data;
deleteNode(root->right,temp2->data);
}
}
}
int main()
{
struct Node *root = NULL;
printf("\n\n");
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
inorder(root);
//deleteNode(root,40);
deleteNode(root,30);
printf("\n\n");
inorder(root);
printf("\n\n");
}

Add function in a trie structure does not work properly

I'm trying to write a function to add words in a trie, and count the number of times it has been added. But it always returns 1.
Can anybody help me?
struct node
{
struct node* next;
struct node* child;
char data;
int value;
};
typedef struct node Node;
Node* getNode(char data)
{
Node* newptr;
newptr = calloc(1,sizeof(Node));
newptr->next = NULL;
newptr -> child = NULL;
newptr->data = data;
newptr -> value = 0;
return newptr;
}
Node* add(Node* parent,char* str)
{
Node* current;
current = parent->child;
while (current != NULL && current->data != str[0])
{
current = current->next;
}
if (current == NULL)
{
current = getNode(str[0]);
if (str[0] == 0)
{
current->value = 1;
return current;
}
return add(current,str + 1);
}
if (str[0] == 0)
{
(current->value)++;
return current;
}
return add(current,str+1);
}
cm: getNode() and Node definitions added!

Resources