diff --git a/bst.c b/bst.c new file mode 100644 index 0000000000000000000000000000000000000000..cae7109d79030f46381e620782f30b7f92a8d19c --- /dev/null +++ b/bst.c @@ -0,0 +1,416 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct Node { + int data; + struct Node* left; + struct Node* right; +} Node; + +typedef struct ParentChildNode { + Node* parent; + Node* child; +} ParentChildNode; + + +ParentChildNode* getLargestNode(Node* node) { + Node* parent = node; + Node* child = node->right; + + while(node->right->right != NULL) { + parent = parent->right; + child = child->right; + node = node->right; + } + ParentChildNode *parentChild = malloc(sizeof(ParentChildNode)); + parentChild->parent = parent; + parentChild->child = child; + return parentChild; +} + +Node* insert_element(Node* node, int val) { + Node* new = (Node*)malloc(sizeof(Node)); + new->data = val; + new->left = NULL; + new->right = NULL; + if(node == NULL) { + node = new; + } + else { + Node* prev = NULL; + Node* ptr = node; + while(ptr != NULL) { + prev = ptr; + if(val < ptr->data) { + ptr = ptr->left; + } + else { + ptr = ptr->right; + } + } + + if(val < prev->data) { + prev->left = new; + } + else { + prev->right = new; + } + } + return node; +} + +void preorder(Node* tree) { + if(tree) { + printf("%d ", tree->data); + preorder(tree->left); + preorder(tree->right); + } +} + +void inorder(Node* tree) { + if(tree) { + inorder(tree->left); + printf("%d ", tree->data); + inorder(tree->right); + } +} + +void postorder(Node* tree) { + if(tree) { + postorder(tree->left); + postorder(tree->right); + printf("%d ", tree->data); + } +} + +Node* insert(Node* node) { + int val; + printf("Masukkan nilai Node: "); scanf("%d", &val); + if(node == NULL) { + return insert_element(node, val); + } + Node* tmp = node; + insert_element(node, val); + return tmp; +} + +Node* findMin(Node* node) { + if(node == NULL) { + printf("The tree has no node\n"); + return node; + } + + Node* tmp = node; + int min_val; + while(tmp) { + min_val = tmp->data; + tmp = tmp->left; + } + + printf("Element terkecil adalah: %d\n", min_val); + return node; +} + +Node* findMax(Node* node) { + if(node == NULL) { + printf("The tree has no node\n"); + return node; + } + + Node* tmp = node; + int max_val; + while(tmp) { + max_val = tmp->data; + tmp = tmp->right; + } + + printf("Element terbesar adalah: %d\n", max_val); + + return node; +} + +Node* delete_node(Node* node) { + int val; + printf("Masukkan nilai node yang akan dihapus: "); + scanf("%d", &val); + + if(node == NULL) { + printf("The tree has no node\n"); + return node; + } + + Node* tmp = node; + Node* parent; + + if(tmp->data == val) { + if(tmp->left == NULL && tmp->right == NULL) { + free(tmp); + node = NULL; + return node; + } + + if(tmp->left == NULL && tmp->right != NULL) { + node = node->right; + free(tmp); + return node; + } + if(tmp->right == NULL && tmp->left != NULL) { + node = node->left; + free(tmp); + return node; + } + + ParentChildNode* largest = getLargestNode(tmp->left); + tmp->data = largest->child->data; + free(largest->child); + free(largest); + + return node; + } + + while(tmp->data != val) { + parent = tmp; + if(val < tmp->data) { + tmp = tmp->left; + } + else { + tmp = tmp->right; + } + + if(tmp == NULL) { + printf("There is no node with value: %d\n", val); + return node; + } + } + + // leaf node + if(tmp->left == NULL && tmp->right == NULL) { + if(parent->left == tmp) { + free(tmp); + parent->left = NULL; + } + else { + free(tmp); + parent->right = NULL; + } + return node; + } + + if(tmp->left == NULL && tmp->right != NULL) { + if(parent->left == tmp) { + parent->left = parent->left->right; + free(tmp); + } + else { + parent->right = parent->right->right; + free(tmp); + } + return node; + } + + if(tmp->left != NULL && tmp->right == NULL) { + if(parent->left == tmp) { + parent->left = parent->left->left; + free(tmp); + } + else { + parent->right = parent->right->left; + free(tmp); + } + return node; + } + + // find largest value on the left subtree (largest always on rightmost leaf) + ParentChildNode* largest = getLargestNode(tmp->left); + if(parent->left == tmp) { + parent->left->data = largest->child->data; + } + else { + parent->right->data = largest->child->data; + } + + free(largest->child); + free(largest); + return node; +} + +int countNode(Node* node) { + if(node == NULL) { + return 0; + } + return countNode(node->left) + countNode(node->right) + 1; +} + +int countInternal(Node* node) { + if(node == NULL || (node->left == NULL & node->right == NULL)) { + return 0; + } + return (countInternal(node->left) + countInternal(node->right) + 1); +} + +int countEksternal(Node* node) { + if(node == NULL) { + return 1; + } + if(node->left == NULL && node->right == NULL) { + return 1; + } + int left = 0; + int right = 0; + if(node->left != NULL) { + left = countEksternal(node->left); + } + if(node->right != NULL) { + right = countEksternal(node->right); + } + return left + right; +} + +int countHeight(Node* node) { + if(node == NULL) { + return 0; + } + int left = countHeight(node->left); + int right = countHeight(node->right); + return (left <= right) ? right+1 : left+1; +} + +Node* convertMirror(Node* node) { + if(node == NULL) { + return 0; + } + convertMirror(node->left); + convertMirror(node->right); + Node* tmp; + tmp = node->left; + node->left = node->right; + node->right = tmp; + + return node; +} + +Node* deleteTree(Node* node) { + if(node == NULL) { + return 0; + } + + deleteTree(node->left); + deleteTree(node->right); + node->left = NULL; + node->right = NULL; + free(node); + node = NULL; + return node; +} + +void jumlahNode(Node* node) { + int jumlah = countNode(node); + printf("Jumlah node: %d", jumlah); +} + +void jumlahIntenal(Node* node) { + int jumlah = countInternal(node); + printf("Jumlah node internal: %d", jumlah); +} + +void jumlahEksternal(Node* node) { + int jumlah = countEksternal(node); + printf("Jumlah node eksternal: %d", jumlah); +} + +void tinggiTree(Node* node) { + int tinggi = countHeight(node); + printf("Tinggi dari tree adalah: %d", tinggi); +} + +Node* ubahMirror(Node* node) { + node = convertMirror(node); + printf("Tree berhasil diubah ke mirror nya"); + return node; +} + +Node* hapusTree(Node* node) { + node = deleteTree(node); + printf("Tree berhasil dihapus"); + return node; +} + +int main() { + Node* tree = NULL; + int option; + do { + printf("\nMain menu\n\n"); + printf("1. Insert Element\n"); + printf("2. Preorder Traversal\n"); + printf("3. Inorder Traversal\n"); + printf("4. Postorder Traversal\n"); + printf("5. Find the smallest element\n"); + printf("6. Find the largest element\n"); + printf("7. Delete an element\n"); + printf("8. Count the total number of nodes\n"); + printf("9. Count the total number of internal nodes\n"); + printf("10. Count the total number of external nodes\n"); + printf("11. Determine the height of the tree\n"); + printf("12. Convert to mirror tree\n"); + printf("13. Delete the tree\n"); + printf("14. Exit\n"); + printf("\n\nMasukkan pilihan Anda: "); scanf("%d", &option); + + switch(option) { + case 1: + tree = insert(tree); + break; + case 2: + printf("Preorder Traversal: "); + preorder(tree); + printf("\n"); + break; + case 3: + printf("Inorder Traversal: "); + inorder(tree); + printf("\n"); + break; + case 4: + printf("Postorder Traversal: "); + postorder(tree); + printf("\n"); + break; + case 5: + tree = findMin(tree); + break; + case 6: + tree = findMax(tree); + break; + case 7: + tree = delete_node(tree); + break; + case 8: + jumlahNode(tree); + break; + case 9: + jumlahIntenal(tree); + break; + case 10: + jumlahEksternal(tree); + break; + case 11: + tinggiTree(tree); + break; + case 12: + tree = ubahMirror(tree); + break; + case 13: + tree = hapusTree(tree); + break; + case 14: + tree = hapusTree(tree); + return 0; + default: + printf("Wrong command\n"); + getchar(); + } + + } while(option != 14); + + return 0; +} \ No newline at end of file