Deleting a node form a binary search tree in C - c

I am trying to write a function to delete a node(any node) from a binary search tree. For some reason, the delete function deletes multiple nodes. It is a recursive function and I am somewhat confused when it comes to resursion. below is my code, can somebody help me figure out what went wrong.
Thanks in advance
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node *nodeP;
typedef struct StudentRoster *StudentRosterP;
struct node
{
nodeP left;
char name[30];
int ID;
nodeP right;
};
struct StudentRoster
{
nodeP root;
int size;
};
//create a new student roster
StudentRosterP newStudentRoster()
{
StudentRosterP new;
new = NULL;
new = malloc(sizeof(struct StudentRoster));
if (new == NULL)
{
fprintf(stderr, "Error: Memory allocation for Student Roster failed\n");
return NULL;
}
else
{
new->root = NULL;
new->size = 0;
return new;
}
}
//creates a new node to store student information
nodeP newNode(char *name, int ID)
{
nodeP new;
new = NULL;
new = malloc(sizeof(struct node));
if(new == NULL)
{
fprintf(stderr, "Memory allocation for the node failed.\n");
return NULL;
}
else
{
new->left = NULL;
new->right = NULL;
new->ID = ID;
strcpy(new->name, name);
return new;
}
}
//function to insert student. this is a helper function, recursive call
void insert(nodeP root, int ID, char * name)
{
if (ID == root->ID)
{
printf("Duplicate IDs not allowed\n");
return;
}
else {
if(ID < root->ID)
{
if(root->left == NULL)
{
root->left = newNode(name, ID);
}
else
{
root = root->left;
insert(root, ID, name);
}
}
else
{
if(root->right == NULL)
{
root->right = newNode(name, ID);
}
else
{
root = root->right;
insert(root, ID, name);
}
}
}
}
//to insert new student
void insertStudentRoster(StudentRosterP roster, char * name, int ID)
{
nodeP root = roster->root;
if(roster->root == NULL) // its empty
{
roster->root = newNode(name, ID);
}
else {
if (ID == roster->root->ID)
{
printf("Duplicate IDs not allowed\n");
return;
}
else
{
insert(roster->root, ID, name);
}
}
}
/*
* Helper function for removeStudentRoster
* finds a node to be deleted and returns its pointer
*/
nodeP findMin(nodeP node)
{
while(node->left != NULL)
{
node = node->left;
}
return node;
}
//removes the node to be deleted
//returns null pointer to the parent function
//This is where I am having problem
nodeP delete(nodeP root, int ID)
{
if(root == NULL)
{
return root;
}
else if(ID < root->ID)
{
root->left = delete(root->left, ID);
}
else if(ID > root->ID)
{
root->right = delete(root->right, ID);
}
else
{
if (root->left == NULL && root->right == NULL)
{
free(root);
root = NULL;
}
else if(root->left == NULL)
{
nodeP temp = root;
root = root->right;
free(temp);
}
else if(root->right == NULL)
{
nodeP temp = root;
root = root->left;
free(temp);
}
else
{
nodeP temp = findMin(root->right);
root->ID = temp->ID;
strcpy(root->name, temp->name);
root->right = delete(root->right, temp->ID);
}
return root;
}
}
/*
* Removes the node containing the matching names
* Parameters: StudentRoster, id
*/
void removeStudentRoster(StudentRosterP roster, int ID)
{
if(roster == NULL)
{
printf("The Student roster does not exist\n");
return;
}
else if(roster->root == NULL)
{
printf("The Student roster is empty\n");
return;
}
else{
//find the node to be deleted
roster->root = delete(roster->root, ID);
}
}
//for printing in ordered
void inOrder(nodeP node)
{
if (node == NULL)
return;
inOrder(node->left);
printf("ID #: %i, Name: %s \n", node->ID, node->name);
inOrder(node->right);
}
/*
* Displays all the entries in the Phone book in order
* Display one person per line, ID followed by first name
*/
void displayStudentRoster(StudentRosterP roster)
{
if (roster->root == NULL) {
printf("The Roster is empty");
return;
}
else
{
inOrder(roster->root);
return;
}
}
int main()
{
StudentRosterP newRoster;
newRoster = newStudentRoster();
insertStudentRoster(newRoster, "Alice", 10);
insertStudentRoster(newRoster, "Jake", 8);
insertStudentRoster(newRoster, "josh", 12);
insertStudentRoster(newRoster, "Alen", 9);
insertStudentRoster(newRoster, "Joe", 11);
removeStudentRoster(newRoster, 11); //it removes the whole roster when removing a node that has no childrens
//when removing the root, it also removes the right child
displayStudentRoster(newRoster);
return (EXIT_SUCCESS);
}

In your delete function, your return is misplaced (only reached when ID matches root->ID). You need to move it past the next closing brace to place it after the else it's in:
}
/* "return root;" was here... */
}
return root; /* ..but should be here. */
}
Additionally, the logic seems wrong for deleting the node when ID does match (in that last else). What you need to do is either move the right branch to the rightmost node in the left branch, or the left branch to the leftmost node of the right branch... then return that branch. So using your findMin() to find the leftmost part of the right branch, we can do:
else
{
nodeP temp = findMin(root->right);
temp->left = root->left;
temp = root;
root = root->right;
free(temp);
}

Related

%s is skipping the entire print line - no user input

What's wrong in my code? I successfully created a tree and everything is working fine except printInorder function and print statement in void main. When I try to print with %s its skipping the entire line.
Can you please help me in resolving this? I even tried fflush but it doesn't help me in my case and I don't try any scanf statement in my code.
struct Tree
{
char data[10];
struct Tree *left;
struct Tree *right;
} * root;
struct Tree *createNode(char data[])
{
struct Tree *node = malloc(sizeof(struct Tree));
strcpy(node->data, data);
node->left = node->right = NULL;
insertTree(node, root, data);
}
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
}
}
else
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->right == NULL)
{
temp->right = currentNode;
printf("data inserted successfully at right");
}
else
{
insertTree(currentNode, temp->right,data);
}
}
}
void printInorder(struct Tree *tmp)
{
if (tmp == NULL)
return;
printInorder(tmp->left);
printf("%s ",tmp->data);
printInorder(tmp->right);
}
void main()
{
struct Tree *root = createNode("saish");
struct Tree *d1 = createNode("ansha");
struct Tree *d2 = createNode("shish");
printf("%s",root->data);
printInorder(root);
}
createNode function doesn't return anything even though it is defined to do so.
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
return node;
}
}

Why does afl fuzzer get segmentation fault?

I did a program in c to do some avl sorting. the program runs well when i test it with no crash. however i ran the program for possible bugs with afl fuzzer and i dont seem to know why i keep getting segmentation fault. below is the tree.c. I dont get bugs when i fuzz without my main.c connecting to the tree.c. Only comes when i send inputs to the tree sorter. Some certain inputs brings about this bug. i made changes to memory allocation but still cant figure out why. i used valgrind, cppcheck and dont get any errors on them. Please why does this error happen and how can i fix it?
an example input from the fuzzer that brings code to segmentation fault
i 3o
i 7ÿo
i
i 3ÿo
i3
3
i 3ÿ3
i83 3
i23ÿo
tree.c
#include "tree.h"
Tree* tree_create(){
Tree *tree = malloc(sizeof(Tree));
tree->root = NULL;
return tree;
}
void tree_node_delete(Node* node) {
if (node == NULL) {
free(node);
return;
}
if (node->left) {
tree_node_delete(node->left);
}
if (node->right) {
tree_node_delete(node->right);
}
free(node->name);
free(node);
}
void tree_delete(Tree* tree) {
tree_node_delete(tree->root);
free(tree);
}
void node_insert(Node* node, int age, char* name, int gen) {
if (age <= node->age){
if (node->left == NULL){
Node* newLeft = calloc(1, sizeof(Node));
newLeft->age = age;
newLeft->name = name;
newLeft->parent = node;
newLeft->right = NULL;
newLeft->left = NULL;
newLeft->isRight = false;
node->left = newLeft;
} else {
node_insert(node->left, age, name, node->left->generation);
}
} else {
if (node->right == NULL){
Node* newRight = calloc(1, sizeof(Node));
newRight->age = age;
newRight->name = name;
newRight->parent = node;
newRight->right = NULL;
newRight->left = NULL;
newRight->isRight = true;
node->right = newRight;
} else {
node_insert(node->right, age, name, node->right->generation);
}
}
}
void tree_insert(Tree* tree, int age, char* name) {
if (tree->root == NULL) {
Node *node = calloc(1, sizeof(Node));
node->name = name;
node->age = age;
node->isRoot = true;
node->right = NULL;
node->left = NULL;
tree->root = node;
} else {
node_insert(tree->root, age, name, 1);
}
}
void tree_erase(Tree* tree, int age, char* name) {
Node* data = tree_find(tree, age, name);
if (data == NULL) {
printf("\nThis node doesn't exist in the current tree\n");
} else {
data->name = NULL;
data->age = NULL;
if (data->grandparent) {
if(data == data->grandparent->grandchildRR) {
data->grandparent->grandchildRR = NULL;
} else if(data == data->grandparent->grandchildRL) {
data->grandparent->grandchildRL = NULL;
} else if(data == data->grandparent->grandchildLR) {
data->grandparent->grandchildLR = NULL;
} else if(data == data->grandparent->grandchildLL) {
data->grandparent->grandchildLL = NULL;
}
}
tree_cleanup(tree, &tree->root, tree->root);
}
}
// Will clean the tree to release previously used nodes
void tree_cleanup(Tree* tree, Node** nodeAdress, Node* node) {
if (node->left) {
tree_cleanup(tree, &node->left, node->left);
}
if (node->right) {
tree_cleanup(tree, &node->right, node->right);
}
if(node->age == NULL && node->name == NULL) {
*nodeAdress = NULL;
free(*nodeAdress);
}
if(node->left == NULL && node->grandchildLL) {
node->left = node->grandchildLL;
node->left->parent = node;
node->left->grandparent = node->parent;
if(node->left->left) {
node->grandchildLL = node->left->left;
} else {
node->grandchildLL = NULL;
}
} else if(node->right == NULL && node->grandchildRL) {
node->right = node->grandchildRL;
node->right->parent = node;
node->right->grandparent = node->parent;
node->right->isRight = true;
if(node->right->left) {
node->grandchildRL = node->right->left;
} else {
node->grandchildLR = NULL;
}
} else if(node->left == NULL && node->grandchildLR) {
node->left = node->grandchildLR;
node->left->parent = node;
node->left->grandparent = node->parent;
node->left->isRight = false;
if (node->left->right) {
node->grandchildLR = node->left->right;
} else {
node->grandchildLR = NULL;
}
} else if(node->right == NULL && node->grandchildRR) {
node->right = node->grandchildRR;
node->right->parent = node;
node->right->grandparent = node->parent;
if (node->right->right) {
node->grandchildRR = node->right->right;
} else {
node->grandchildRR = NULL;
}
}
}
//Calculate the weight and the balance factor of the node.
void tree_balance_factor(Tree* tree, Node* node) {
if (node == NULL) {
return;
}
if (node->left) {
tree_balance_factor(tree, node->left);
}
if (node->right) {
tree_balance_factor(tree, node->right);
}
if (node->parent) {
if (node->isRight == true) {
if (node->weightRight > node->weightLeft) {
node->parent->weightRight = node->weightRight+1;
} else {
node->parent->weightRight = node->weightLeft+1;
}
} else if (node->isRight == false) {
if (node->weightRight > node->weightLeft) {
node->parent->weightLeft = node->weightRight+1;
} else {
node->parent->weightLeft = node->weightLeft+1;
}
}
}
node->balancefactor = node->weightRight - node->weightLeft;
if (node->balancefactor == 2) {
if(node->right->balancefactor == 1) {
leftRotation(tree, node);
} else {
rightPermutation(tree, node);
leftRotation(tree, node);
}
} else if (node->balancefactor == -2) {
if(node->left->balancefactor == -1) {
rightRotation(tree, node);
} else {
leftPermutation(tree, node);
rightRotation(tree, node);
}
}
}
// Reset the weightings and set up the grandchilds and grandparents relations back
void tree_balance_factor_reset(Tree* tree, Node* node) {
if (node == NULL) {
return;
}
if (node->left) {
tree_balance_factor_reset(tree, node->left);
}
if (node->right) {
tree_balance_factor_reset(tree, node->right);
}
node->weightLeft = 0;
node->weightRight = 0;
if(node->right) {
if(node->right->right) {
node->grandchildRR = node->right->right;
node->right->parent = node;
node->right->right->grandparent = node;
} else {
node->grandchildRR = NULL;
}
if(node->right->left) {
node->grandchildRL = node->right->left;
node->right->parent = node;
node->right->left->grandparent = node;
} else {
node->grandchildRL = NULL;
}
}
if(node->left) {
if(node->left->left) {
node->grandchildLL = node->left->left;
node->left->parent = node;
node->left->left->grandparent = node;
} else {
node->grandchildLL = NULL;
}
if (node->left->right) {
node ->grandchildLR = node->left->right;
node->left->parent = node;
node->left->right->grandparent = node;
} else {
node->grandchildLR = NULL;
}
}
}
void setGen (Node* node) {
if(node->parent) {
node->generation = node->parent->generation +1;
}
if (node->left) {
setGen(node->left);
}
if (node->right) {
setGen(node->right);
}
}
void leftRotation(Tree* tree, Node* node ) {
Node* newNode = node->right;
if(node->isRoot == true) {
tree->root = newNode;
newNode->isRoot = true;
node->isRoot = false;
newNode->parent = NULL;
} else if (node->isRoot = false){
newNode->parent = node->parent;
if(node->isRight) {
newNode->parent->right = newNode;
} else {
newNode->parent->left = newNode;
}
}
newNode->left = node;
node->parent = newNode;
node->right = NULL;
}
void rightRotation(Tree* tree, Node* node) {
Node* newNode = node->left;
if(node->isRoot == true) {
tree->root = newNode;
newNode->isRoot = true;
node->isRoot = false;
newNode->parent = NULL;
} else {
newNode->parent = node->parent;
if(node->isRight) {
newNode->parent->right = newNode;
} else {
newNode->parent->left = newNode;
}
}
newNode->right = node;
node->parent = newNode;
node->left = NULL;
}
void rightPermutation(Tree* tree, Node* node) {
Node* newNode = node->right;
node->right = newNode->left;
node->right->right = newNode;
newNode->left = NULL;
newNode->parent = node->right;
node->right->parent = node;
}
void leftPermutation(Tree* tree, Node* node) {
Node* newNode = node->left;
node->left = newNode->right;
node->left->left = newNode;
newNode->right = NULL;
newNode->parent = node->left;
node->left->parent = node;
}
void tree_print_node(Node* node){
if (node == NULL) {
printf("null");
return;
}
printf("[");
printf("{\"%d\":\"%s\"},", node->age, node->name);
tree_print_node(node->left);
printf(",");
tree_print_node(node->right);
printf("]");
}
void tree_print(Tree* tree, int printNewline){
if (tree == NULL) {
printf("null");
return;
}
tree_print_node(tree->root);
if (printNewline){
printf("\n");
}
}
Node* node_find(Node* node, int age, char* name) {
int i = strcmp(node->name, name);
if (node->age == age && i == 0) {
return node;
}
if (age <= node->age) {
if (node->left) {
return node_find(node->left, age, name);
} else {
return NULL;
}
} else {
if (node->right) {
return node_find(node->right, age, name);
} else {
return NULL;
}
}
}
Node* tree_find(Tree* tree, int age, char* name) {
if(tree->root != NULL) {
return node_find(tree->root, age, name);
} else {
printf("\nNo node inserted in the tree yet\n");
return NULL;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "tree.h"
int main() {
char* commandBuffer = (char*)malloc(sizeof(char) * 20);
Tree *tree = tree_create();
for(;;) {
if (tree == NULL){
tree = tree_create();
}
tree_balance_factor_reset(tree, tree->root);
tree_balance_factor(tree, tree->root);
tree_balance_factor_reset(tree, tree->root);
printf("\n- Enter <i age name> to insert a node in the tree \n- Enter <e age name> to erase a node \n- Enter <c age name> to check the tree \n- Enter <p> to "
"print the tree \n- Enter <x> the delete the tree \n- Enter <q> to exit the program\n\n" );
fgets(commandBuffer, 20, stdin);
int b = strlen(commandBuffer);
if(b>=19) {
int clearVar;
while (((clearVar = getchar()) != '\n' && clearVar != EOF)) {
}
};
// Quit on EOF or 'q'
if (feof(stdin) || *commandBuffer == 'q' ){
break;
}
tree = handleString(commandBuffer, tree);
};
free(tree);
free(commandBuffer);
return 0;
}
Tree* handleString(char command[], Tree *tree){
if (command == NULL){
fprintf(stderr, "Invalid command; null pointer\n");
return tree;
}
switch(command[0]){
case 'i':
insert(command, tree);
break;
case 'e':
erase(command, tree);
break;
case 'c':
check(command, tree);
break;
case 'p':
tree_print(tree, 1);
break;
case 'x':
tree_delete(tree);
return NULL;
default:
fprintf(stderr, "Invalid command string: %s\n", command);
break;
}
return tree;
}
Tree* insert(char* command, Tree* tree) {
int age;
char* name = malloc(sizeof(char) * 20);
if (2 != sscanf(command, "i %d %19s", &age, name)){
fprintf(stderr, "Failed to parse insert command: not enough parameters filled\n");
// return NULL;
}
if (tree == NULL){
tree = tree_create();
}
tree_insert(tree, age, name);
return tree;
}
int erase(char* command, Tree* tree) {
int age;
char* name = malloc(sizeof(char) * 20);
if (2 != sscanf(command, "e %d %19s", &age, name)){
fprintf(stderr, "Failed to parse erase command: not enough parameters filled\n");
// return 0;
}
tree_erase(tree, age, name);
return 0;
}
void check(char* command, Tree* tree) {
int age;
char* name = malloc(sizeof(char) * 20);
if (2 != sscanf(command, "c %d %19s", &age, name)){
fprintf(stderr, "Failed to parse check command\n");
}
Node* result = tree_find(tree, age, name);
if (result){
printf("\nThe node is present\n");
} else {
printf("\nThe node could not be found\n");
}
}
tree.h
#ifndef C_IMPLEMENTATION_TREE_H
#define C_IMPLEMENTATION_TREE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct Node {
/**
* Left child of this node
*/
struct Node* left;
/**
* Right child of this node
*/
struct Node* right;
/**
* The age of the data in this node
*/
int generation;
int balancefactor;
int weightLeft;
int weightRight;
struct Node* parent;
struct Node* grandparent;
struct Node* grandchildLL;
struct Node* grandchildLR;
struct Node* grandchildRL;
struct Node* grandchildRR;
bool isRight;
bool parentIsRight;
bool isRoot;
int age;
/**
* The name of the data in this node
*/
char* name;
} Node;
typedef struct Tree {
Node *root;
} Tree;
/**
* Create a new tree
* #param age The age value for the first data point
* #param name The name value for the first data point
* #return The root Node of the tree
*/
Tree* tree_create();
/**
* Delete an entire tree. This will delete the passed Node and all children below it
* #param node The root Node of the tree to delete.
*/
void tree_delete(Tree* tree);
/**
* Insert a new data point into the tree
*
* #param tree The root node of the tree
* #param age The age part of the data point
* #param name The name part of the data point
*/
void tree_insert(Tree* tree, int age, char* name);
/**
* Remove a data point from a tree
* #param tree The root node of the tree
* #param age The age part of the data point to delete
* #param name The name part of the data point to delete
*/
void tree_erase(Tree* tree, int age, char* name);
/**
* Prints a tree in the following format:
* [<data>, <left>, <right>]
* where the elements above have the following format:
* <data> {<age:int>: "<name:string>"}
* <left>, <right>: The same format as the root node. When a child node is NULL, the string NULL is to be printed.
*/
void tree_cleanup(Tree* tree, Node** nodeAdress, Node* node);
/**
* Will free and release null nodes.
*/
void setGen(Node* node);
void tree_balance_factor(Tree* tree,Node* node);
void tree_balance_factor_reset(Tree* tree, Node* node);
void leftRotation(Tree* tree, Node* node);
void rightRotation(Tree* tree,Node* node);
void rightPermutation(Tree* tree, Node* node);
void leftPermutation(Tree* tree, Node* node);
void tree_print(Tree *tree, int printNewline);
Node* tree_find(Tree* node, int age, char* name);
#endif //C_IMPLEMENTATION_TREE_H
I managed to reproduce SIGSEGV in gdb. It is hapened in function rightPermutation, which does not check if pointer to left is NULL or not:
void rightPermutation(Tree* tree, Node* node) {
Node* newNode = node->right;
node->right = newNode->left;
In case the node->left is NULL, you will get SIGSEGV on next line:
node->right->right = newNode;
Further, you can see details of the message and data of the Node structure.
Program received signal SIGSEGV, Segmentation fault.
0x000055555555570c in rightPermutation (tree=0x555555758280, node=0x555555758d20) at tree.c:322
322 node->right->right = newNode;
(gdb) p node
$1 = (Node *) 0x555555758d20
(gdb) p *node
$2 = {left = 0x555555758ed0, right = 0x0, generation = 0, balancefactor = 2, weightLeft = 1, weightRight = 3, parent = 0x0, grandparent = 0x555555758b70,
grandchildLL = 0x0, grandchildLR = 0x0, grandchildRL = 0x0, grandchildRR = 0x555555758c00, isRight = false, parentIsRight = false, isRoot = true, age = 0,
name = 0x555555758d00 ""}

Deleting a node from a binary search tree without recursion

I have a binary search tree. I want to delete a node from it:
void deleteANode(struct node *head, int value) {
//let us find the node
struct node *temp = head;
struct node *parent = NULL;
//let us find the node
while (temp != NULL) {
if (value > temp->data) {
parent = temp;
temp = temp->right;
} else
if (value < temp->data) {
parent = temp;
temp = temp->left;
} else {
//let us check for child nodes
//
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp = NULL;
printf("Set temp null.\n");
free(temp);
break;
} else
if (temp->left == NULL || temp->right == NULL) {
printf("Deleting a one child.\n");
//one of the child is null
if (temp->left != NULL) {
parent->left = temp->left;
} else {
parent->right = temp->right;
}
free(temp);
} else {
printf("Deleting two child parent.\n");
//both of them are not NULL
//need to find the pre-order successor
struct node *temp2 = temp->right;
while (temp2->left != NULL) {
temp2 = temp2->left;
}
//found the successor.
temp->data = temp2->data;
free(temp);
}
break;
}
}
}
I am trying to delete a leaf node in this block:
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp->data = NULL;
printf("Set temp null.\n");
free(temp);
break;
}
But the above code doesn't work.
I am calling the above method:
deleteANode(head, 3);
The preorder traversal is remains same before and after:
5 4 3 10 7 20 Deleting a leaf. Set temp null.
=============== 5 4 3 10 7 20
What am I doing wrong.
Updated as per #pstrjds comments:
if (temp->left == NULL && temp->right == NULL ) {
printf("Deleting a leaf.\n");
parent->left = NULL;
parent->right = NULL;
free(temp);
temp = NULL;
printf("Set temp null.\n");
break;
}
It's working fine for leaf node. Need to work for node with two children.
In the block of code which is deleting a leaf you are not actually freeing the node nor are you updating the parent node to no longer point to it.
if ( temp -> left == NULL && temp -> right == NULL )
{
printf("Deleting a leaf.\n");
if (parent->left == temp)
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
free(temp);
temp = NULL;
printf("Set temp null.\n");
break;
}
You could actually remove the line temp = NULL and change the break; to a return statement.
Does your code really work?
It should be like this:
printf("Deleting two child parent.\n");
Node* temp2 = temp->right;
while(temp2->left != NULL)
{
parent = temp2;
temp2 = temp2->left;
}
temp->data = temp2->data;
parent->left = NULL;
delete temp2;
return;
Java Solution
// Java program to demonstrate delete operation in binary search tree
class BinarySearchTree
{
/* Class containing left and right child of current node and key value*/
class Node
{
int key;
Node left, right;
public Node(int item)
{
key = item;
left = right = null;
}
}
// Root of BST
Node root;
// Constructor
BinarySearchTree()
{
root = null;
}
// This method mainly calls deleteRec()
void deleteKey(int key)
{
root = deleteRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node deleteRec(Node root, int key)
{ Node x=root;
Node parent =null;
/* Base Case: If the tree is empty */
while(x!=null)
{
if(x.key>key)
{ parent=x;
x=x.left;
}
else if(x.key<key)
{parent=x;
x=x.right;
}
else
{
if(x.left==null&&x.right==null)
{
System.out.println(x.key+"y1");
if(parent.left==x)
parent.left=null;
else if(parent.right==x)
parent.right=null;
x=null;
break;
}
else
{
System.out.println(x.key+"y2");
if(x.left==null)
{
if(parent.right==x)
parent.right=x.right;
else if(parent.left==x)
parent.left=x.right;
System.out.println(x.key+"yes");
x=null;
break;
}
else if(x.right==null)
{
if(parent.left==x)
parent.left=x.left;
else if(parent.right==x)
parent.right=x.left;
x=null;
break;
}
else
{
Node temp=x;
Node px=null;
temp=temp.right;
while(temp.left!=null)
{ px=temp;
temp=temp.left;
}
x.key=temp.key;
if(px.left==temp)
px.left=null;
else if(px.left==temp)
px.right=null;
temp=null;
break;
}
}
}
}
return root;
}
int minValue(Node root)
{
int minv = root.key;
while (root.left != null)
{
minv = root.left.key;
root = root.left;
}
return minv;
}
// This method mainly calls insertRec()
void insert(int key)
{
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key)
{
/* If the tree is empty, return a new node */
if (root == null)
{
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
// This method mainly calls InorderRec()
void inorder()
{
inorderRec(root);
}
// A utility function to do inorder traversal of BST
void inorderRec(Node root)
{
if (root != null)
{
inorderRec(root.left);
System.out.print(root.key + " ");
inorderRec(root.right);
}
}
// Driver Program to test above functions
public static void main(String[] args)
{
BinarySearchTree tree = new BinarySearchTree();
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
System.out.println("Inorder traversal of the given tree");
tree.inorder();
System.out.println("\nDelete 20");
tree.deleteKey(20);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
System.out.println("\nDelete 30");
tree.deleteKey(30);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
System.out.println("\nDelete 50");
tree.deleteKey(50);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
}
}

Pointer in function to linked list not updating element in 1 case

I am using a struct like this
struct infoM {
char* direction;
int key;
};
typedef struct nodeM{
struct infoM nodeInfo;
struct nodeM *next;
struct nodeM *prev;
} node;
typedef node list;
I have one function that returns the wanted node by a specific field
node * search(list *l, char* direction) {}
And this is my function to remove elements from the list
int delete(list *l, char* direction) {
node *tmp = search(l, direction);
if (tmp != NULL) {
node *ant = tmp->prev;
node *seg = tmp->next;
if (seg != NULL) {
if (ant != NULL) {
ant->next = seg;
seg->prev = ant;
free(tmp);
return 1;
} else { //prev null
seg->prev = NULL;
*l = *seg;
tmp = NULL;
free(tmp);
return 1;
}
} else { //next null
if (ant == NULL) {
l->nodeInfo.key = somevalue;
l->next = NULL;
l->prev = NULL;
return 1;
} else {
printf("Here is the problem\n");
ant->next = NULL;
free(tmp);
return 1;
}
}
} else { //tmp nulo
perror("Error delete : node null\n");
return 0;
}
}
If I have 4 elements in the list, 1234 and I delete first first element everything is okay and returns 234. If I delete the last element it returns 23 seems to work great. But if I try to delete the last element now the function does nothing despite being the same case that when it is 234 and I don't understand why. The list is not being updated.
In the main I am using the list like this :
list a;
delete(&a, "whatever");
What am I doing wrong ?
This is the code for search
node * createnode(){
node *tmp = (node *) malloc (sizeof(node));
return tmp;
}
node * search(list *l, char* direction) {
node *tmp = createnode();
if (l->nodeInfo.key == 777) {
perror("Error search: empty list\n");
return NULL;
}
tmp=l;
while((strcmp(direction, tmp->nodeInfo.direction) !=0) && (tmp->next != NULL)) {
tmp = tmp->next;
}
if (strcmp(direction, tmp->nodeInfo.direction) == 0) {
return tmp;
} else {
perror("Error search: element not found\n");
return NULL;
}
}

Delete function in Binary Tree in C

I'm writing the basic functions for binary tree and everything seems to compile and run, but when i try to use my delete function it doesn't do anything.
After executing i get the same sequence of numbers, so i'm trying to figure out what's wrong with the Delete function, is it logically correct?
#include <stdio.h>
#include <stdlib.h>
typedef struct treeNode
{
int data;
struct treeNode *left;
struct treeNode *right;
}treeNode;
treeNode *Insert(treeNode *node, int data)
{
if(node == NULL)
{
treeNode *temp;
temp = malloc(sizeof(treeNode));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
if(data > (node->data))
{
node->right = Insert(node->right, data);
}
else if(data < (node->data))
{
node->left = Insert(node->left, data);
}
return node;
}
treeNode *Delete(treeNode *node, int data)
{
if(node == NULL)
{
printf("element not found\n");
}
else if(data < node->data)
{
node->left = Delete(node->left, data);
}
else if(data > node->data)
{
node->right = Delete(node->right, data);
}
return node;
}
treeNode *Find(treeNode *node, int data)
{
if(node == NULL)
{
return NULL;
}
if(data > node->data)
{
return Find(node->right, data);
}
else if(data < node->data)
{
return Find(node->left, data);
}
else
{
return node;
}
}
void Print(treeNode *node)
{
if(node == NULL)
{
return;
}
Print(node->left);
printf("%d", node->data);
Print(node->right);
}
int main()
{
treeNode *root = NULL;
root = Insert(root, 5);
root = Insert(root, 8);
root = Insert(root, 6);
root = Insert(root, 4);
root = Insert(root, 3);
root = Insert(root, 9);
root = Insert(root, 10);
root = Insert(root, 19);
Print(root);
printf("\n");
root = Delete(root, 5);
root = Delete(root, 8);
Print(root);
printf("\n");
treeNode *temp;
temp = Find(root, 8);
if(temp == NULL)
{
printf("Element 8 not found\n");
}
else
{
printf("Element 8 found\n");
}
temp = Find(root, 5);
if(temp == NULL)
{
printf("element 5 not found\n");
}
else
{
printf("element 5 found\n");
}
}
Basically i was only replacing the node with itself, but this can be solved by replacing the deleted node with the minimum element in the right subtree or the maximum element in the left subtree.
The function that works:
treeNode * Delete(treeNode *node, int data)
{
treeNode *temp;
if(node==NULL)
{
printf("Element Not Found");
}
else if(data < node->data)
{
node->left = Delete(node->left, data);
}
else if(data > node->data)
{
node->right = Delete(node->right, data);
}
else
{
/* Now We can delete this node and replace with either minimum element
in the right sub tree or maximum element in the left subtree*/
if(node->right && node->left)
{
/* Here we will replace with minimum element in the right sub tree */
temp = FindMin(node->right);
node -> data = temp->data;
/* As we replaced it with some other node, we have to delete that node */
node -> right = Delete(node->right,temp->data);
}
else
{
/* If there is only one or zero children then we can directly
remove it from the tree and connect its parent to its child */
temp = node;
if(node->left == NULL)
node = node->right;
else if(node->right == NULL)
node = node->left;
free(temp); /* temp is longer required */
}
}
return node;
}

Resources