#include #include #include #include "bst.h" #include "queue.h" /* 3. Двоичное дерево поиска Узел — словарь: `{'val': '123', 'left': None, 'right': None}.` Функции: def bst_insert(root, name, phone) — рекурсивно или итеративно вставляет, возвращает новый корень (если корень меняется). def bst_find(root, name) — поиск. def bst_delete(root, name) — удаление, возвращает новый корень. def bst_list_all(root) — центрированный обход (рекурсивно собирает записи в отсортированном порядке). */ bst_node* create_bst_node(char name[NAME_LEN], char phone[PHONE_LEN]) { bst_node* node = (bst_node*)malloc(sizeof(bst_node)); strcpy(node->name, name); strcpy(node->phone, phone); node->left = NULL; node->right = NULL; return node; } bst_node* bst_minimum(bst_node* node) { if (node->left == NULL) return node; return bst_minimum(node->left); } bst_node* bst_maximum(bst_node* node) { if (node->right == NULL) return node; return bst_maximum(node->right); } void print_bst(bst_node node) { //printf("value: %d\n", node.value); printf("name: %s, phone: %s\n", node.name, node.phone); } void bst_inorder_traversal(bst_node* HEAD) { if (HEAD != NULL) { bst_inorder_traversal(HEAD->left); print_bst(*HEAD); bst_inorder_traversal(HEAD->right); } } void bst_preorder_traversal(bst_node* HEAD) { if (HEAD != NULL) { print_bst(*HEAD); bst_preorder_traversal(HEAD->left); bst_preorder_traversal(HEAD->right); } } bst_node* bst_search(bst_node* HEAD, char target_name[NAME_LEN]) { /* Node search(x : Node, k : T): if x == null or k == x.key return x if k < x.key return search(x.left, k) else return search(x.right, k) */ if ((HEAD == NULL) || strcmp(HEAD->name, target_name) == 0) { return HEAD; } if (strcmp(target_name, HEAD->name) < 0) { return bst_search(HEAD->left, target_name); } else { return bst_search(HEAD->right, target_name); } } bst_node* bst_insert(bst_node* HEAD, char name[NAME_LEN], char phone[PHONE_LEN]) { /* Node insert(x : Node, z : T): // x — корень поддерева, z — вставляемый ключ if x == null return Node(z) // подвесим Node с key = z else if z < x.key x.left = insert(x.left, z) else if z > x.key x.right = insert(x.right, z) return x */ if (HEAD == NULL) { return create_bst_node(name, phone); } else if (strcmp(name, HEAD->name) < 0) { HEAD->left = bst_insert(HEAD->left, name, phone); } else if (strcmp(name, HEAD->name) > 0) { HEAD->right = bst_insert(HEAD->right, name, phone); } return HEAD; } bst_node* bst_delete(bst_node* root, char target_name[NAME_LEN]) { // корень поддерева, удаляемый ключ if (root == NULL) return root; if (strcmp(target_name, root->name) < 0) root->left = bst_delete(root->left, target_name); else if (strcmp(target_name, root->name) > 0) root->right = bst_delete(root->right, target_name); else { if (root->left != NULL && root->right != NULL) { strcpy(root->name, bst_minimum(root->right)->name); strcpy(root->phone, bst_minimum(root->right)->phone); root->right = bst_delete(root->right, root->name); } else { bst_node* temp = root; if (root->left != NULL) root = root->left; else root = root->right; free(temp); } } return root; } void delete_bst(bst_node* root) { if (root == NULL) return; else { delete_bst(root->left); delete_bst(root->right); free(root); } } void printTree(bst_node* node, int depth) { if (node == NULL) return; printTree(node->right, depth + 1); for (int i = 0; i < depth; i++) printf("\t"); //printf("%d\n", node->value); print_bst(*node); printTree(node->left, depth + 1); } void treeLevelTraversal(bst_node* node) { if (!node) return; Queue q; Queue* hq = &q; queueInit(hq); queuePush(hq, node); while(!queueEmpty(hq)) { bst_node* hn = queuePop(hq); //printf("%d\n", hn->value); print_bst(*hn); if(hn->left) queuePush(hq, hn->left); if(hn->right) queuePush(hq, hn->right); }; };