From 0e7a03e78472f26d448a09eea79f23919b66408e Mon Sep 17 00:00:00 2001 From: GordStep Date: Thu, 7 May 2026 14:28:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Изменение структуры лабораторной работы - Завершение библитеки для Бинарного дерева поиска --- .../sorce/bin_search_tree/bst.c | 208 ++++++++++++++++++ .../sorce/bin_search_tree/bst.h | 37 ++++ .../sorce/bin_search_tree/queue.c | 42 ++++ .../sorce/bin_search_tree/queue.h | 17 ++ .../sorce/{ => linked_list}/linked_list.c | 43 +++- .../sorce/{ => linked_list}/linked_list.h | 0 stepushovgs/data-structures/sorce/main.c | 2 +- stepushovgs/data-structures/sorce/main_tree.c | 171 ++++++-------- stepushovgs/data-structures/sorce/swap.c | 40 ++++ 9 files changed, 443 insertions(+), 117 deletions(-) create mode 100644 stepushovgs/data-structures/sorce/bin_search_tree/bst.c create mode 100644 stepushovgs/data-structures/sorce/bin_search_tree/bst.h create mode 100644 stepushovgs/data-structures/sorce/bin_search_tree/queue.c create mode 100644 stepushovgs/data-structures/sorce/bin_search_tree/queue.h rename stepushovgs/data-structures/sorce/{ => linked_list}/linked_list.c (61%) rename stepushovgs/data-structures/sorce/{ => linked_list}/linked_list.h (100%) create mode 100644 stepushovgs/data-structures/sorce/swap.c diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/bst.c b/stepushovgs/data-structures/sorce/bin_search_tree/bst.c new file mode 100644 index 0000000..80e06f1 --- /dev/null +++ b/stepushovgs/data-structures/sorce/bin_search_tree/bst.c @@ -0,0 +1,208 @@ +#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); + + }; +}; diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/bst.h b/stepushovgs/data-structures/sorce/bin_search_tree/bst.h new file mode 100644 index 0000000..1bf960d --- /dev/null +++ b/stepushovgs/data-structures/sorce/bin_search_tree/bst.h @@ -0,0 +1,37 @@ +#define NAME_LEN 20 +#define PHONE_LEN 20 + +typedef struct bst_node +{ + //int value; + + char name[NAME_LEN]; + char phone[PHONE_LEN]; + + struct bst_node* right; + struct bst_node* left; +}bst_node; + +bst_node* create_bst_node(char name[NAME_LEN], char phone[PHONE_LEN]); + +bst_node* bst_minimum(bst_node* node); + +bst_node* bst_maximum(bst_node* node); + +void print_bst(bst_node node); + +void bst_inorder_traversal(bst_node* HEAD); + +void bst_preorder_traversal(bst_node* HEAD); + +bst_node* bst_search(bst_node* HEAD, char target_name[NAME_LEN]); + +bst_node* bst_insert(bst_node* HEAD, char name[NAME_LEN], char phone[PHONE_LEN]); + +bst_node* bst_delete(bst_node* root, char target_name[NAME_LEN]); + +void treeLevelTraversal(bst_node* node); + +void printTree(bst_node* node, int depth); + +void delete_bst(bst_node* root); diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/queue.c b/stepushovgs/data-structures/sorce/bin_search_tree/queue.c new file mode 100644 index 0000000..adea3cb --- /dev/null +++ b/stepushovgs/data-structures/sorce/bin_search_tree/queue.c @@ -0,0 +1,42 @@ +#include + +#include "queue.h" + +int queueEmpty(Queue* q) +{ + return (q->head == q->tail); +} + +int size(Queue* q) +{ + if (q->head > q->tail) + return QUEUE_MAX_LENGTH - q->head + q->tail; + else + return q->tail - q->head; +} + +void queuePush(Queue* q, void* ptr) +{ + if (size(q) != QUEUE_MAX_LENGTH) + { + q->p[q->tail] = ptr; + q->tail = (q->tail + 1) % QUEUE_MAX_LENGTH; + } +}; + +void queueInit(Queue* q) +{ + q->head = 0; + q->tail = 0; +} + +void* queuePop(Queue* q) +{ + if (queueEmpty(q)) + return NULL; + void* x = q->p[q->head]; + q->head = (q->head + 1) % QUEUE_MAX_LENGTH; + + return x; +}; + diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/queue.h b/stepushovgs/data-structures/sorce/bin_search_tree/queue.h new file mode 100644 index 0000000..5bbdfce --- /dev/null +++ b/stepushovgs/data-structures/sorce/bin_search_tree/queue.h @@ -0,0 +1,17 @@ +#define QUEUE_MAX_LENGTH 100 + +typedef struct Queue { + void* p[QUEUE_MAX_LENGTH]; + unsigned int head; + unsigned int tail; +} Queue; + +int queueEmpty(Queue* q); + +void queuePush(Queue* q, void* p); + +void* queuePop(Queue* q); + +void queueInit(Queue* q); + +int size(Queue* q); diff --git a/stepushovgs/data-structures/sorce/linked_list.c b/stepushovgs/data-structures/sorce/linked_list/linked_list.c similarity index 61% rename from stepushovgs/data-structures/sorce/linked_list.c rename to stepushovgs/data-structures/sorce/linked_list/linked_list.c index 04231ba..0eeb9e7 100644 --- a/stepushovgs/data-structures/sorce/linked_list.c +++ b/stepushovgs/data-structures/sorce/linked_list/linked_list.c @@ -1,9 +1,27 @@ +#include #include #include #include #include "linked_list.h" +/* +Связный список (LinkedListPhoneBook) + +Узел представляется словарём: `{'name': 'Имя', 'phone': '123', 'next': None}.` + +Функции: + +def ll_insert(head, name, phone) — проходит до конца (или сразу добавляет в конец) и возвращает новую голову (если вставка в начало) или изменяет список по ссылке. Удобнее возвращать новую голову, если вставка может быть в начало. + +def ll_find(head, name) — ищет узел, возвращает телефон или None. + +def ll_delete(head, name) — удаляет узел, возвращает новую голову. + +def ll_list_all(head) — собирает все записи в список и сортирует (сортировка вынесена отдельно). +*/ + + int getListNodeLength(Node* HEAD) { int len = 0; @@ -82,21 +100,28 @@ void printAllNodes(Node* head) Node* deleteNode(Node* HEAD, char target_name[NAME_BUFF_SIZE]) { - Node* privious = HEAD; - Node* current = HEAD->next; + Node* previous = NULL; + Node* current = HEAD; - while (current != NULL) + if (current != NULL && strcmp(target_name, current->name_) == 0) { - if (strcmp(target_name, current->name_) == 0) - { - privious->next = current->next; - break; - } + HEAD = current->next; + free(current); - privious = current; + return HEAD; + } + + while (current != NULL && strcmp(target_name, current->name_) == 0) + { + previous = current; current = current->next; } + if (current == NULL) return HEAD; + + previous->next = current->next; + free(current); + return HEAD; } diff --git a/stepushovgs/data-structures/sorce/linked_list.h b/stepushovgs/data-structures/sorce/linked_list/linked_list.h similarity index 100% rename from stepushovgs/data-structures/sorce/linked_list.h rename to stepushovgs/data-structures/sorce/linked_list/linked_list.h diff --git a/stepushovgs/data-structures/sorce/main.c b/stepushovgs/data-structures/sorce/main.c index 8b73cdf..15b3a51 100644 --- a/stepushovgs/data-structures/sorce/main.c +++ b/stepushovgs/data-structures/sorce/main.c @@ -2,7 +2,7 @@ #include #include -#include "linked_list.h" +#include "linked_list/linked_list.h" #define NAME_BUFF_SIZE 50 #define PHONE_BUFF_SIZE 12+1 // +1 for end symbol diff --git a/stepushovgs/data-structures/sorce/main_tree.c b/stepushovgs/data-structures/sorce/main_tree.c index 9890883..9b264a7 100644 --- a/stepushovgs/data-structures/sorce/main_tree.c +++ b/stepushovgs/data-structures/sorce/main_tree.c @@ -1,113 +1,29 @@ #include #include -#include -#include "linked_list.h" -/* -3. Двоичное дерево поиска -Узел — словарь: `{'name': 'Имя', 'phone': '123', 'left': None, 'right': None}.` +#include "bin_search_tree/bst.h" -Функции: +#define COUNT_NUMBERS 64 -def bst_insert(root, name, phone) — рекурсивно или итеративно вставляет, возвращает новый корень (если корень меняется). - -def bst_find(root, name) — поиск. - -def bst_delete(root, name) — удаление, возвращает новый корень. - -def bst_list_all(root) — центрированный обход (рекурсивно собирает записи в отсортированном порядке). -*/ - -typedef struct bst_node -{ - char name[NAME_BUFF_SIZE]; - char phone[PHONE_BUFF_SIZE]; - - struct bst_node* right; - struct bst_node* left; -}bst_node; - -bst_node* create_bst_node(char name[NAME_BUFF_SIZE], char phone[PHONE_BUFF_SIZE]) +int isInArr(int arr[], int len, int target) { - bst_node* node = (bst_node*)malloc(sizeof(bst_node)); + for (int i = 0; i < len; i++) + { + if (arr[i] == target) return 1; + } - strcpy(node->name, name); - strcpy(node->phone, phone); - - node->left = NULL; - node->right = NULL; - - return node; + return 0; } -void print_bst(bst_node node) +char get_dozen(int number) { - printf("name: %s phone: %s\n", node.name, node.phone); + return (char)'0' + number % 10; +} +char get_units(int number) +{ + return (char)'0' + number / 10; } -void bst_inorder_traversal(bst_node* HEAD) -{ - if (HEAD != NULL) - { - bst_inorder_traversal(HEAD->left); - print_bst(*HEAD); - bst_inorder_traversal(HEAD->right); - } -} - -bst_node* bst_search(bst_node* HEAD, char target_name[NAME_BUFF_SIZE]) -{ - /* - 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(HEAD->name, target_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_BUFF_SIZE], char phone[PHONE_BUFF_SIZE]) -{ - /* - 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(HEAD->name, name) > 0) - { - HEAD->left = bst_insert(HEAD->left, name, phone); - } - else if (strcpy(HEAD->name, name) < 0) - { - HEAD->right = bst_insert(HEAD->right, name, phone); - } - return HEAD; -} int main() { @@ -115,15 +31,56 @@ int main() //bst_node* head = create_bst_node("name", "phone"); bst_node* head = NULL; - char name[] = "name0"; - - head = bst_insert(head, name, "phone"); - - print_bst(*head); - head = bst_insert(head, "name1", "phone1"); - head = bst_insert(head, "name2", "phone2"); - head = bst_insert(head, "name3", "phone3"); - + + int arr[COUNT_NUMBERS] = {0}; + char name[NAME_LEN] = "name_xx"; + char phone[PHONE_LEN] = "phone_xx"; + int temp = 0; + for (int i = 0; i < COUNT_NUMBERS; i++) + { + do + { + temp = rand() % 100; + } + while (isInArr(arr, i - 1, temp)); + + arr[i] = temp; + + name[5] = get_dozen(temp); + name[6] = get_units(temp); + + phone[6] = get_dozen(temp); + phone[7] = get_units(temp); + + + head = bst_insert(head, name, phone); + printf("%d ", arr[i]); + } + + printf("\n\ninorder traversal: \n"); bst_inorder_traversal(head); + + printf("\n\npreorder traversal: \n"); + bst_preorder_traversal(head); + + char tar_name[NAME_LEN] = "name_44"; + + printf("\n\nУдаляем элемент с значением %s:\n", tar_name); + + head = bst_delete(head, tar_name); + + bst_inorder_traversal(head); + + + printf("\n\nВывод дерева:\n"); + + printTree(head, 0); + + printf("\n\nОбход в ширину:\n"); + treeLevelTraversal(head); + + + + delete_bst(head); return 0; } diff --git a/stepushovgs/data-structures/sorce/swap.c b/stepushovgs/data-structures/sorce/swap.c new file mode 100644 index 0000000..3a6cc08 --- /dev/null +++ b/stepushovgs/data-structures/sorce/swap.c @@ -0,0 +1,40 @@ +#include + +int Partition_Hoa(int arr[], int l, int r) +{ + int p = arr[(l + r) / 2]; + int i = l; + int j = r; + + while (1) + { + // #print(p) + while (arr[i] <= p) i++; + while (arr[j] > p) j--; + + if (i >= j) return j; + + swap(arr[i], arr[j]); + i++; + j--; + } +} +void QuickSort(int arr[], int l, int r) +{ + if (l < r): + { + int s = Partition_Hoa(arr, l, r); + QuickSort(arr, l, s-1); + QuickSort(arr, s+1, r); + } +} + + +int main() +{ + int arr[] = {2, 56, 10, 5, 2, 6, 9, 6, 3, 923, 3, 2, 1}; + + + + return 0; +}