Skip to content

Commit

Permalink
remove node from binary tree
Browse files Browse the repository at this point in the history
  • Loading branch information
jainkhere committed May 3, 2022
1 parent a518536 commit 8e66683
Showing 1 changed file with 136 additions and 2 deletions.
138 changes: 136 additions & 2 deletions binary_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void add_value_to_tree (NODE ** addr_of_root, int insert_value) {
// 4. make root parent of new_node
(*new_node).left = right_child;
(*right_child).parent = new_node;
right_child = new_node;
(*root).right = new_node;
(*new_node).parent = root;
return;

Expand All @@ -127,15 +127,140 @@ void add_value_to_tree (NODE ** addr_of_root, int insert_value) {
// node_to_find - value of node to find
NODE * find_node (NODE * root, int node_to_find) {
// if root is null then return null
if (root == NULL)
return NULL;

// if value of root is equal to node_to_find
// then return root
if ((*root).value == node_to_find) {
return root;
}

// recursively call find_node on left subtree
// if node found then return it.
NODE * foundNode = find_node((*root).left, node_to_find);
if (foundNode != NULL)
return foundNode;

// recursively call find_node on right subtree
// return this node
foundNode = find_node((*root).right, node_to_find);
return foundNode;
}

// Given root of 2 trees, merge both of them
// r1 -> root of tree one
// r2 -> root of tree two
NODE * merge_two_trees (NODE * r1, NODE * r2) {
// Check if any one of both the trees is null
// if any one is null, then return
if (r1 == NULL)
return r1;
if (r2 == NULL)
return r1;

// If neither is null, then call add_value_to_tree function
// with r1 as root, and value of r2 as the value to add.
add_value_to_tree(&r1, (*r2).value);

// call merge_two_trees recursively on left and right child of r2.
r1 = merge_two_trees(r1, (*r2).left);
r1 = merge_two_trees(r1, (*r2).right);

// return root node
return r1;
}

void remove_node (NODE ** addr_of_root, int value_to_remove) {
// Create a root node from address of root.
NODE * root = *addr_of_root;

// Search node in tree, remove only if node found
NODE * node_to_remove = find_node(root, value_to_remove);

// return if node_to_remove is null
if (node_to_remove == NULL)
return;

// Create node for parent, left and right child of node_to_remove
NODE * parent = (*node_to_remove).parent;
NODE * left_child = (*node_to_remove).left;
NODE * right_child = (*node_to_remove).right;


// If parent is NULL, this means that node_to_remove is root node
// 1. Remove root node using free.
// 2. Set parent of left and right child to null
// 3. Merge left and right subtree using merge_two_trees function
// Get root of merged subtree in NODE new_root
// 4. Update value at address of root to new_root
if (parent == NULL) {
free(root);
(*left_child).parent = NULL;
(*right_child).parent = NULL;

NODE * new_root = merge_two_trees(left_child, right_child);
*addr_of_root = new_root;
return;
}

// If left_child of node_to_remove is not NULL
// 1. Set parent as parent of left_child
// 2. if node_to_remove is equal to value of left child of parent then
// set left_child as left child of parent
// otherwise set left_child as right child of parent
// 3. Set parent of right_child to NULL
// 4. Merge current tree with tree whose root is right_child
// Get root of merged subtree in NODE new_root
// 5. Remove node_to_remove using free.
// 6. Update value at address of root to new_root
if (left_child != NULL) {
(*left_child).parent = parent;

if (node_to_remove == (*parent).left) {
(*parent).left = left_child;
}
else {
(*parent).right = left_child;
}

(*right_child).parent = NULL;

NODE * new_root = merge_two_trees(root, right_child);
*addr_of_root = new_root;
free(node_to_remove);
return;
}

// If right_child of node_to_remove is not NULL
// 1. Set parent as parent of right_child
// 2. If node_to_remove is equal to value of left child of parent then
// set right_child as left_child of parent
// otherwise set right child as right child of parent
// 3. Remove node_to_remove using free.
if (right_child != NULL) {
// printf("Value of right of NTR -> \n", (*right_child).value);
(*right_child).parent = parent;

if (node_to_remove == (*parent).left) {
(*parent).left = right_child;
}
else {
(*parent).right = right_child;
}

free(right_child);
}

// If no above condition is met then that means we have to remove leaf node
if (node_to_remove == (*parent).left) {
(*parent).left = NULL;
}
else {
(*parent).right = NULL;
}

free(node_to_remove);
}

// Inorder traversal of tree
Expand Down Expand Up @@ -174,8 +299,17 @@ int main(void) {

printf("\n");

NODE * node = find_node(root, 40);
NODE * node = find_node(root, 15);
printf("Value of found node -> %d\n", (*node).value);

remove_node(&root, 15);

// node = find_node(root, 10);
// printf("Value of found node -> %d\n", (*node).value);

// Print tree using in order traversal
printf("Inorder traversal -> ");
print_in_order(root);

return 0;
}

0 comments on commit 8e66683

Please sign in to comment.