From 2459fbf85caf7526416e9c22f475d5a05cab19e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Gabriel=20Ten=C3=B3rio=20Oliveira?= <51039620+VictorG-028@users.noreply.github.com> Date: Wed, 30 Oct 2019 01:31:46 -0300 Subject: [PATCH] Create bst.c operations: - insert_nose() - search_node() - remove_node() - print_pre_order() - print_in_order() - print_pos_order() Each operation is tested in the main --- Data Structure & Algorithm/graphs/bst.c | 230 ++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 Data Structure & Algorithm/graphs/bst.c diff --git a/Data Structure & Algorithm/graphs/bst.c b/Data Structure & Algorithm/graphs/bst.c new file mode 100644 index 0000000..03f65fa --- /dev/null +++ b/Data Structure & Algorithm/graphs/bst.c @@ -0,0 +1,230 @@ +#include +#include + + +struct node +{ + int value; + struct node* right; + struct node* left; +}; + + +struct node* create_node(int value) +{ + struct node* new_node = (struct node*)malloc( sizeof(struct node) ); + new_node->right = NULL; + new_node->left = NULL; + + new_node->value = value; + + return new_node; +} + + +struct node* insert_node(int value, struct node* current) +{ + if(current == NULL) + { + return create_node(value); // Create and link the new leaf to the last node visited + } + else if(value > current->value) + { + // the insert return create_node() when the next node is NULL + // so, the new node will be linked to a previous node + current->right = insert_node(value, current->right); + } + else if(value < current->value) + { + current->left = insert_node(value, current->left); + } + + /* when it finishes creating a node or the value is already in the tree, this + return will finish the recursion whitout changing the tree */ + return current; + +} + + +struct node* search_node(int searched_value, struct node* current) +{ + if(current == NULL) // case where it didn't find the node + { + return NULL; + } + else if(searched_value < current->value) + { + return search_node(searched_value, current->left); // keep searching in the left direction + } + else if(searched_value > current->value) + { + return search_node(searched_value, current->right); // keep searching in the right direction + } + // else if(searched_value == current->value) + return current; // if found the node, return it +} + + +struct node* remove_node(int searched_value, struct node* current) +{ + // same as insert until the the else + if(current == NULL) + { + return current; + } + else if(searched_value > current->value) + { + // current->right will recive the new or the same node that should be linked to it + current->right = remove_node(searched_value, current->right); + return current; + } + else if(searched_value < current->value) + { + // current->left will recive the new or the same node that should be linked to it + current->left = remove_node(searched_value, current->left); + return current; + } + else // searched_value == current->value + { + if(current->right == NULL && current->left == NULL) // case 1: leaf case + { + free(current); + + return NULL; // return NULL to the previous node + } + else if(current->right == NULL) // case 2.1: 1 left children + { + struct node* left_node = current->left; + + free(current); + + return left_node; // return the left node to the previous node + } + else if(current->left == NULL) // case 2.2: 1 right children + { + struct node* right_node = current->right; + + free(current); + + return right_node; // return the right node to the previous node + } + else // case 3: 2 childrem case + { + struct node* min_value_from_right_subtree = current->right; + + // while to find the min_value_from_right_subtree + while(min_value_from_right_subtree->left != NULL) + { + min_value_from_right_subtree = min_value_from_right_subtree->left; + } + + // swap the value from the carrent node and the min_value_from_right_subtree node + current->value = min_value_from_right_subtree->value; + min_value_from_right_subtree->value = searched_value; + + current->right = remove_node(searched_value, current->right); // will be removed as case 1 now + return current; + } + } +} + + +void print_pre_order(struct node* current) +{ + if(current != NULL) + { + printf("%i ", current->value); + print_pre_order(current->left); + print_pre_order(current->right); + } +} + + +void print_in_order(struct node* current) +{ + if(current != NULL) + { + print_in_order(current->left); + printf("%i ", current->value); + print_in_order(current->right); + } +} + + +void print_pos_order(struct node* current) +{ + if(current != NULL) + { + print_pos_order(current->left); + print_pos_order(current->right); + printf("%i ", current->value); + } +} + + +int main() +{ + struct node* root = NULL; + + ///// inserting test ///// + + root = insert_node(5, root); // linking the root to the first insertion + insert_node(10, root); + insert_node(1, root); + insert_node(0, root); + insert_node(3, root); + insert_node(7, root); + insert_node(15, root); + + // tree after inserting 5, 10, 1, 0, 3, 7, 15 + // 5 + // 1 10 + // 0 3 7 15 + + print_pre_order(root); // output expected: 5 1 0 3 10 7 15 + printf("\n"); + + print_in_order(root); // output expected: 0 1 3 5 7 10 15 5 + printf("\n"); + + print_pos_order(root); // output expected: 0 3 1 7 15 10 5 + printf("\n\n"); + + + ///// removing test ///// + + root = remove_node(0, root); // remove case 1: leaf case + + root = remove_node(1, root); // remove case 2.2: 1 right childrem + + root = remove_node(10, root); // remove case 3: 2 childrem case + + root = remove_node(20, root); // testing removing a non existing value + + root = remove_node(5, root); // testing removing the root + + // tree after removing 0, 1, 10, 20 and 5 + // 7 + // 3 15 + + print_pre_order(root); // output expected: 7 3 15 + printf("\n"); + + print_in_order(root); // output expected: 3 7 15 + printf("\n"); + + print_pos_order(root); // output expected: 3 15 7 + printf("\n\n"); + + + ///// searching test ///// + + struct node* searched_node = search_node(7, root); + + if(searched_node != NULL) + { + printf("The 7 node should be found \n\n"); + } + + return 0; +}