struct treeNode {
char word[10];
struct treeNode *left;
struct treeNode *right;
struct treeNode *father;
};
struct treeNode* getMin(struct treeNode *node)
{
while (node->left != NULL) {
node = node->left;
}
return node;
}
void deleteNode(struct treeNode *node) {
char tempForDelete[10];
struct treeNode *parent = node->father;
if (node->left == NULL && node->right == NULL)
{
if (node != root)
{
if (parent->left == node) {
parent->left = NULL;
}
else {
parent->right = NULL;
}
}
else {
root = NULL;
}
free(node);
}
else if (node->left != NULL && node->right !=NULL)
{
struct treeNode* successor = getMin(node->right);
strcpy(tempForDelete, successor->word);
deleteNode(successor);
strcpy(node->word,tempForDelete);
}
else {
struct treeNode* child;
if (node->left != NULL)
child = node->left;
else
child = node->right;
if (node != root)
{
if (node == parent->left) {
parent->left = child;
}
else {
parent->right = child;
}
}
else {
root = child;
}
free(node);
}
}
void filterDictionary(struct treeNode *root)
{
if (root == NULL) {
return;
}
filterDictionary(root->left);
filterDictionary(root->right);
if (checkNode(root) == 1)
deleteNode(root);
}
checkNode just check if the node has to be deleted, i keep getting the same errors from valgrind: Invalid write of size
Address 0x4a4e4c8 is 24 bytes inside a block of size 48 free'd
(A lot of these :,) )
If needed i can also provide the code for deletNode but i'm pretty sure that the function works correctly.
(I also tried the iterative way but it was the same thing).
Has anyone any ideas what i'm doing wrong? I've been trying to figure this out for days and i can't find a way :((
Thanks in advance!
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 ""}
So i've been running and testing my code and everything seemed to have been working until i added 2 more functions for Pre-order and Post-order traversals of my tree.
The assignment was to create a linked list and tree for an input file with a random set of numbers. The linked list and tree traversals all need to be printed out in separate functions and i can't find where i went wrong.
i keep getting
Segmentation Fault (core dumped)
Here is my code:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node
{
int num;
struct node *next;
};
struct tree
{
int numt;
struct tree *left;
struct tree *right;
};
typedef struct node LINK;
typedef struct tree branch;
int searchList(int number, LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
if (current->num == number)
return 1; // Found it.
current = current->next;
}
return 0; // Did not find it.
}
LINK *insertList(int number, LINK *head)
{
LINK *current, *temp;
if (searchList(number, head) == 1) return head;
temp = (LINK *)malloc(sizeof(LINK));
temp->num = number;
if (head == NULL)
{
head = temp;
temp->next = NULL;
return head;
}
current = head;
if (current->num == number)
{
temp->next = current;
head = temp;
return head;
}
current = head;
while (current != NULL)
{
if (current->next == NULL || current->next->num == number)
{
temp->next = current->next;
current->next = temp;
return head;
}
current = current->next;
}
}
void printList(LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
printf("%i\n", current->num);
current = current->next;
}
}
LINK *freeList(LINK *head)
{
LINK *current, *temp;
current = head;
while (current != NULL)
{
temp = current;
current = current->next;
free(temp);
}
free(head);
head = NULL;
return head;
}
void freeTree(branch *leaf)
{
if(leaf != 0)
{
freeTree(leaf->left);
freeTree(leaf->right);
free(leaf);
}
}
void insert(int new, branch **leaf)
{
if(*leaf == 0)
{
*leaf = (struct tree*) malloc(sizeof(struct tree));
(*leaf)->numt = new;
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(new < (*leaf)->numt)
{
insert(new, &(*leaf)->left);
}
else if(new > (*leaf)->numt)
{
insert(new, &(*leaf)->right);
}
}
void printInorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printf("%i ", leaf->numt);
printInorder(leaf->right);
}
void printPreorder(branch *leaf)
{
if (leaf == NULL)
return;
printf("%i ", leaf->numt);
printInorder(leaf->left);
printInorder(leaf->right);
}
void printPostorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printInorder(leaf->right);
printf("%i ", leaf->numt);
}
int main (void)
{
int t;
FILE *stream = fopen("hw9.data", "r");
LINK *head;
branch *leaf;
head = NULL;
int number;
while (1)
{
fscanf(stream, "%i", &number);
if (feof(stream)) break;
insert(number, &leaf);
head = insertList(number, head);
}
fclose(stream);
printf("\nPrinting List: \n");
printList(head);
printf("\n\nPrinting in order\n");
printInorder(leaf);
printf("\n\nPrinting Pre order\n");
printPreorder(leaf);
printf("\n\nPrinting Post order\n");
printPostorder(leaf);
head = freeList(head);
freeTree(leaf);
head = NULL;
return 0;
}
branch *leaf; is not initialized. Your code expects leaf pointers to be NULL. Try branch *leaf = NULL;
Also, it looks like freeList frees head twice which is undefined behavior.
I wrote binary search tree by C language, which data is string, and I have problem when I tried to type data.
Error show on line 14, I think root->data is NULL cause it, but I don't know how to solve.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
Node *parent;
Node *left;
Node *right;
char *data;
};
Node *insert(Node *root, char *data) {
if (root == NULL) {
Node *tmp;
tmp = (Node *)malloc(sizeof(Node));
root->data = data; // <--- Line 14
tmp -> left = tmp -> right = NULL;
return tmp;
}
if (strcmp(data, root->data) > 0) {
root -> right = insert(root->right, data);
} else if (strcmp(data, root->data) < 0) {
root -> left = insert(root->left, data);
}
return root;
}
void Print(Node *root){
if (root == NULL) return;
Print(root->left);
printf("%s\n", root->data);
Print(root->right);
}
int main() {
Node *root = NULL;
char input[21];
while (scanf("%s", input) != EOF) {
root = insert(root, input);
}
Print(root);
return 0;
}
In your function:
Node *insert(Node *root, char *data) {
if (root == NULL) {
Node *tmp; // is this really needed?
tmp = (Node *)malloc(sizeof(Node)); // did your mean root = malloc(..) ?
root->data = data; // <--- root is always NULL, from test above
/* ... */
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;
}