Обновление

- Изменение структуры лабораторной работы
- Завершение библитеки для Бинарного дерева поиска
This commit is contained in:
GordStep 2026-05-07 14:28:06 +03:00
parent b638d6c169
commit 0e7a03e784
9 changed files with 443 additions and 117 deletions

View File

@ -0,0 +1,208 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
};
};

View File

@ -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);

View File

@ -0,0 +1,42 @@
#include <stdlib.h>
#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;
};

View File

@ -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);

View File

@ -1,9 +1,27 @@
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#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

View File

@ -1,113 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -0,0 +1,40 @@
#include <stdio.h>
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;
}