forked from UNN/2026-rff_mp
Compare commits
No commits in common. "develop" and "main" have entirely different histories.
100
stepushovgs/.gitignore → .gitignore
vendored
100
stepushovgs/.gitignore → .gitignore
vendored
|
|
@ -160,103 +160,3 @@ cython_debug/
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
# Prerequisites
|
|
||||||
*.d
|
|
||||||
|
|
||||||
# Object files
|
|
||||||
*.o
|
|
||||||
*.ko
|
|
||||||
*.obj
|
|
||||||
*.elf
|
|
||||||
|
|
||||||
# Linker output
|
|
||||||
*.ilk
|
|
||||||
*.map
|
|
||||||
*.exp
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Libraries
|
|
||||||
*.lib
|
|
||||||
*.a
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
*.i*86
|
|
||||||
*.x86_64
|
|
||||||
*.hex
|
|
||||||
|
|
||||||
# Debug files
|
|
||||||
*.dSYM/
|
|
||||||
*.su
|
|
||||||
*.idb
|
|
||||||
*.pdb
|
|
||||||
|
|
||||||
# Kernel Module Compile Results
|
|
||||||
*.mod*
|
|
||||||
*.cmd
|
|
||||||
.tmp_versions/
|
|
||||||
modules.order
|
|
||||||
Module.symvers
|
|
||||||
Mkfile.old
|
|
||||||
dkms.conf
|
|
||||||
|
|
||||||
# debug information files
|
|
||||||
*.dwo
|
|
||||||
|
|
||||||
#################################
|
|
||||||
############## Go ###############
|
|
||||||
#################################
|
|
||||||
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
||||||
#
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Code coverage profiles and other test artifacts
|
|
||||||
*.out
|
|
||||||
coverage.*
|
|
||||||
*.coverprofile
|
|
||||||
profile.cov
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
|
||||||
go.work.sum
|
|
||||||
|
|
||||||
# env file
|
|
||||||
.env
|
|
||||||
|
|
||||||
# Editor/IDE
|
|
||||||
# .idea/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
!go.mod
|
|
||||||
|
|
||||||
#################################
|
|
||||||
########### Obsidian ############
|
|
||||||
#################################
|
|
||||||
|
|
||||||
.obsidian/
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
427
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -1,122 +0,0 @@
|
||||||
## Практические графики
|
|
||||||
### Информация о тестировании
|
|
||||||
- Общее число записей: 20000
|
|
||||||
- Каждый замер повторялся: 20 раз
|
|
||||||
- Количество существующих записей для случайного поиска: 1000
|
|
||||||
- Количество несуществующих записей для поиска: 500
|
|
||||||
- Количество элементов для удаления: 1000
|
|
||||||
|
|
||||||
![[insert.pdf]]
|
|
||||||
**Тестирование вставки (рис. 1)**
|
|
||||||
|
|
||||||
![[search.pdf]]
|
|
||||||
**Тестирование поиска (рис. 2)**
|
|
||||||
|
|
||||||
![[delete.pdf]]
|
|
||||||
**Тестирование удаления (рис. 3)**
|
|
||||||
## Анализ результатов
|
|
||||||
|
|
||||||
### Как порядок входных данных влияет на скорость вставки в BST (деградация до O(n) на отсортированных данных)?
|
|
||||||
|
|
||||||
По определению, при вставке отсортированных данных, структура бинарного дерева поиска вырождается в связный список.
|
|
||||||
Для визуализации этого в тесте выводятся высота и количество элементов в дереве:
|
|
||||||
Для случайных данных вывод выглядит примерно так:
|
|
||||||
```
|
|
||||||
Высота дерева: 28, элементов: 8634
|
|
||||||
```
|
|
||||||
Для сортированных данных же:
|
|
||||||
```
|
|
||||||
Высота дерева: 8634, элементов: 8634
|
|
||||||
```
|
|
||||||
Заметим, что при случайных данных скорость вставки в бинарное дерево почти лишь немного уступает по скорости хеш-таблице. При сортированных данных из-за рекурсивной реализации вставки бинарное дерево проигрывает связному списку(который имеет линейную сложность вставки)
|
|
||||||
|
|
||||||
### Почему хеш-таблица почти не чувствительна к порядку.
|
|
||||||
Хеш-таблица не чувствительна к порядку данных, так как использует для распределения элементов хеш значения данных (сложность операции одинакова для любых однотипных данных) и после производит вставку в связный список(в моей реализации проходит по списку и вставляет данные в конец). Поэтому хеш-таблица ни на одном из этапов не сравнивает данные, следовательно их порядок не влияет на скорость.
|
|
||||||
|
|
||||||
### Почему связный список всегда медленен при поиске.
|
|
||||||
Операция поиска в связном списке имеет линейную сложность $O(n)$ не зависимо от порядка данных, что можно видеть на графике (см. рис. 2). Для бинарного дерева поиска эта сложность в лучшем случае $O(\log(N))$, а в худшем $O(N)$. Для хеш-таблицы сложность вставки $O(1)$, с хорошей хеш-функцией и низким заполнением.
|
|
||||||
|
|
||||||
### Как удаление работает в каждой структуре.
|
|
||||||
#### Связный список
|
|
||||||
Находим элемент перед удаляем элементом, и заменяем его поле `next` на `next.next`, то есть теперь он указывает на элемент, который идёт после удаляемого элемента:
|
|
||||||
``` Go
|
|
||||||
current := ll.head
|
|
||||||
|
|
||||||
for current.next != nil {
|
|
||||||
if current.next.data.Name == targetName {
|
|
||||||
current.next = current.next.next
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Бинарное дерево поиска
|
|
||||||
После того, как мы нашли узел, который необходимо удалить, у нас возможны три случая.
|
|
||||||
|
|
||||||
Случай 1: У удаляемого узла нет правого ребенка.
|
|
||||||
В этом случае мы просто перемещаем левого ребенка (3) на место удаляемого узла(5). В результате дерево будет выглядеть так:
|
|
||||||
```
|
|
||||||
Удаляем элемент со значением 5
|
|
||||||
ДО УДАЛЕНИЯ: ПОСЛЕ УДАЛЕНИЯ:
|
|
||||||
|
|
||||||
[8] [8]
|
|
||||||
/ \ / \
|
|
||||||
[5] [10] [3] [10]
|
|
||||||
/ / \
|
|
||||||
[3] [1] [4]
|
|
||||||
/ \
|
|
||||||
[1] [4]
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Случай 2: У удаляемого узла есть только правый ребенок, у которого, в свою очередь нет левого ребенка.
|
|
||||||
В этом случае нам надо переместить правого ребенка(8) удаляемого узла (5) на его место.
|
|
||||||
```
|
|
||||||
Удаляем элемент со значением 5
|
|
||||||
До удаления: После удаления:
|
|
||||||
|
|
||||||
[10] [10]
|
|
||||||
/ \ / \
|
|
||||||
[5] [12] [8] [12]
|
|
||||||
/ \ / \
|
|
||||||
[1] [8] [1] [9]
|
|
||||||
\
|
|
||||||
[9]
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Случай 3: У удаляемого узла есть первый ребенок, у которого есть левый ребенок.
|
|
||||||
В этом случае место удаляемого узла занимает крайний левый ребенок правого ребенка удаляемого узла.
|
|
||||||
Давайте посмотрим, почему это так. Мы знаем о поддереве, начинающемся с удаляемого узла следующее:
|
|
||||||
|
|
||||||
- Все значения справа от него больше или равны значению самого узла.
|
|
||||||
- Наименьшее значение правого поддерева — крайнее левое.
|
|
||||||
|
|
||||||
Мы должны поместить на место удаляемого узел со значением, меньшим или равным любому узлу справа от него. Для этого нам необходимо найти наименьшее значение в правом поддереве. Поэтому мы берем крайний левый узел правого поддерева.
|
|
||||||
|
|
||||||
```
|
|
||||||
Удаляем элемент со значением 5
|
|
||||||
До удаления: После удаления:
|
|
||||||
|
|
||||||
[10] [10]
|
|
||||||
/ \ / \
|
|
||||||
[5] [12] [7] [12]
|
|
||||||
/ \ / \
|
|
||||||
[1] [9] [1] [9]
|
|
||||||
/ /
|
|
||||||
[7] [8]
|
|
||||||
\
|
|
||||||
[8]
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Хеш-таблица
|
|
||||||
Находим индекс элемента в таблица, далее производим удаление элемента в связном списке, который соответствует этому индексу.
|
|
||||||
|
|
||||||
|
|
||||||
# Вывод
|
|
||||||
Мы реализовали и протестировали три различные структуры хранения данных: связный список, бинарное дерево поиска и хеш-таблица. Сравнили скорость операций вставки, удаления и поиска для каждой структуры.
|
|
||||||
Если не важен порядок хранения и извлечения данных, то хеш-таблица лучший выбор для быстрых вставки, удаления и поиска.
|
|
||||||
Если нужно хранить данные с возможностью быстрого отсортированного обхода, то стоит выбрать бинарное дерево поиска.
|
|
||||||
Если нужно хранить данные в порядке поступления(например очередь), то стоит выбрать связный список.
|
|
||||||
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
#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);
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#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);
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
#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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
#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);
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
module source
|
|
||||||
|
|
||||||
go 1.26.3
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
#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;
|
|
||||||
|
|
||||||
Node* current = HEAD;
|
|
||||||
while (current != NULL)
|
|
||||||
{
|
|
||||||
len++;
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавление в конец
|
|
||||||
Node* insert(Node* head, char name[NAME_BUFF_SIZE], char phone[PHONE_BUFF_SIZE], int show)
|
|
||||||
{
|
|
||||||
Node* newNode = (Node*)malloc(sizeof(Node));
|
|
||||||
|
|
||||||
strcpy_s(newNode->name_, NAME_BUFF_SIZE, name);
|
|
||||||
strcpy_s(newNode->phone_, PHONE_BUFF_SIZE, phone);
|
|
||||||
newNode->next = NULL;
|
|
||||||
|
|
||||||
printf("Data: %s %s\n", name, phone);
|
|
||||||
printf("New Data: %s %s\n", newNode->name_, newNode->phone_);
|
|
||||||
|
|
||||||
if (head == NULL)
|
|
||||||
{
|
|
||||||
printf("\nNew list\n");
|
|
||||||
head = newNode;
|
|
||||||
return newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* last = head;
|
|
||||||
int ind = 0;
|
|
||||||
while (last->next != NULL)
|
|
||||||
{
|
|
||||||
if (show == 1)
|
|
||||||
printf("%d \n", ind++);
|
|
||||||
last = last->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
last->next = newNode;
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* find(Node* HEAD, char target_name[NAME_BUFF_SIZE])
|
|
||||||
{
|
|
||||||
Node* current = HEAD;
|
|
||||||
|
|
||||||
while (current != NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (strcmp(target_name, current->name_) == 0)
|
|
||||||
{
|
|
||||||
return current->phone_;
|
|
||||||
}
|
|
||||||
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Вывод всех элементов
|
|
||||||
void printAllNodes(Node* head)
|
|
||||||
{
|
|
||||||
Node* current = head;
|
|
||||||
int ind = 0;
|
|
||||||
|
|
||||||
while (current != NULL)
|
|
||||||
{
|
|
||||||
printf("Ind: %d\nName: %s\nPhone: %s\n", ind++, current->name_, current->phone_);
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* deleteNode(Node* HEAD, char target_name[NAME_BUFF_SIZE])
|
|
||||||
{
|
|
||||||
Node* previous = NULL;
|
|
||||||
Node* current = HEAD;
|
|
||||||
|
|
||||||
if (current != NULL && strcmp(target_name, current->name_) == 0)
|
|
||||||
{
|
|
||||||
HEAD = current->next;
|
|
||||||
free(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* listAll(Node* HEAD)
|
|
||||||
{
|
|
||||||
if (HEAD == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int len = getListNodeLength(HEAD);
|
|
||||||
Node* current = HEAD;
|
|
||||||
|
|
||||||
Node* list = (Node*)malloc(len * sizeof(Node));
|
|
||||||
|
|
||||||
int ind = 0;
|
|
||||||
while (current != NULL)
|
|
||||||
{
|
|
||||||
list[ind++] = *current;
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printNode(Node node)
|
|
||||||
{
|
|
||||||
printf("%s ", node.name_);
|
|
||||||
printf("%s\n", node.phone_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printListNode(Node* list, int length)
|
|
||||||
{
|
|
||||||
printf("\n\n%d\n", length);
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
printNode(list[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#define NAME_BUFF_SIZE 50
|
|
||||||
#define PHONE_BUFF_SIZE 12+1 // +1 for end symbol
|
|
||||||
|
|
||||||
typedef struct Node
|
|
||||||
{
|
|
||||||
char name_[NAME_BUFF_SIZE];
|
|
||||||
char phone_[PHONE_BUFF_SIZE];
|
|
||||||
struct Node* next;
|
|
||||||
} Node;
|
|
||||||
|
|
||||||
typedef struct LinkedListPhoneNumbers {
|
|
||||||
Node* HEAD;
|
|
||||||
} LinkedListPhoneNumbers;
|
|
||||||
|
|
||||||
Node* insert(Node* head, char name[NAME_BUFF_SIZE], char phone[PHONE_BUFF_SIZE], int show);
|
|
||||||
void printAllNodes(Node* head);
|
|
||||||
void printNode(Node node);
|
|
||||||
|
|
||||||
char* find(Node* HEAD, char target_name[NAME_BUFF_SIZE]);
|
|
||||||
|
|
||||||
|
|
||||||
Node* deleteNode(Node* HEAD, char target_name[NAME_BUFF_SIZE]);
|
|
||||||
|
|
||||||
|
|
||||||
Node* listAll(Node* HEAD);
|
|
||||||
|
|
||||||
void printListNode(Node list[], int length);
|
|
||||||
|
|
||||||
int getListNodeLength(Node* HEAD);
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "linked_list/linked_list.h"
|
|
||||||
|
|
||||||
#define NAME_BUFF_SIZE 50
|
|
||||||
#define PHONE_BUFF_SIZE 12+1 // +1 for end symbol
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
Node* list = NULL;
|
|
||||||
char phone[] = "1234";
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
{
|
|
||||||
char num[3];
|
|
||||||
sprintf_s(num, 3, "%d", i);
|
|
||||||
|
|
||||||
char name[] = "name ";
|
|
||||||
strcat_s(name, 9, num);
|
|
||||||
printf("%d %s %s\n", i, name, phone);
|
|
||||||
list = insert(list, name, phone, 0);
|
|
||||||
}
|
|
||||||
char test_name[] = "name 20";
|
|
||||||
char test_phone[] = "phone 343";
|
|
||||||
|
|
||||||
list = insert(list, test_name, test_phone, 1);
|
|
||||||
|
|
||||||
printAllNodes(list);
|
|
||||||
|
|
||||||
printf("\n%s\n", find(list, test_name));
|
|
||||||
|
|
||||||
strcpy_s(test_name, NAME_BUFF_SIZE, "name 10");
|
|
||||||
list = deleteNode(list, test_name);
|
|
||||||
|
|
||||||
printAllNodes(list);
|
|
||||||
|
|
||||||
Node* listNodes = listAll(list);
|
|
||||||
printListNode(listNodes, getListNodeLength(list));
|
|
||||||
|
|
||||||
free(listNodes);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "bin_search_tree/bst.h"
|
|
||||||
|
|
||||||
#define COUNT_NUMBERS 64
|
|
||||||
|
|
||||||
int isInArr(int arr[], int len, int target)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
if (arr[i] == target) return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char get_dozen(int number)
|
|
||||||
{
|
|
||||||
return (char)'0' + number % 10;
|
|
||||||
}
|
|
||||||
char get_units(int number)
|
|
||||||
{
|
|
||||||
return (char)'0' + number / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
printf("hello world!\n");
|
|
||||||
|
|
||||||
//bst_node* head = create_bst_node("name", "phone");
|
|
||||||
bst_node* head = NULL;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
package csvwriter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/csv"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BenchmarkResult struct {
|
|
||||||
Structure string
|
|
||||||
Mode string
|
|
||||||
Operation string
|
|
||||||
Time float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BenchmarkResult) ToString() string {
|
|
||||||
return fmt.Sprintf("%s %s %s %f", b.Structure, b.Mode, b.Operation, b.Time)
|
|
||||||
}
|
|
||||||
func (b *BenchmarkResult) ToStrings() []string {
|
|
||||||
return []string{b.Structure, b.Mode, b.Operation, fmt.Sprintf("%f", b.Time)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Создаём пустой csv файл с заголовками
|
|
||||||
func CreateEmptyCSV(dir, name string) error {
|
|
||||||
filename := filepath.Join(dir, name)
|
|
||||||
|
|
||||||
file, err := os.Create(filename)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
writer := csv.NewWriter(file)
|
|
||||||
defer writer.Flush()
|
|
||||||
header := []string{"Structure", "Mode", "Operation", "Time"}
|
|
||||||
writer.Write(header)
|
|
||||||
|
|
||||||
return writer.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendRaw дописывает произвольные строки в CSV
|
|
||||||
func AppendRaw(results []BenchmarkResult) error {
|
|
||||||
|
|
||||||
filename := filepath.Join("results", "benchmarks.csv")
|
|
||||||
|
|
||||||
fileExists := true
|
|
||||||
isEmpty := true
|
|
||||||
if info, err := os.Stat(filename); err == nil {
|
|
||||||
isEmpty = info.Size() == 0
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
fileExists = false
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
writer := csv.NewWriter(file)
|
|
||||||
defer writer.Flush()
|
|
||||||
|
|
||||||
// Если файл новый или пустой, записываем заголовки
|
|
||||||
if !fileExists || isEmpty {
|
|
||||||
header := []string{"Structure", "Mode", "Operation", "Time"}
|
|
||||||
if err := writer.Write(header); err != nil {
|
|
||||||
return fmt.Errorf("не удалось записать заголовки: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rows := make([][]string, len(results))
|
|
||||||
|
|
||||||
for i, res := range results {
|
|
||||||
rows[i] = res.ToStrings()
|
|
||||||
// fmt.Println(res.ToStrings())
|
|
||||||
}
|
|
||||||
|
|
||||||
return writer.WriteAll(rows) // WriteAll пишет всё сразу
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package data_struct
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type MyData struct {
|
|
||||||
Name string
|
|
||||||
Phone string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewData(name, phone string) *MyData {
|
|
||||||
return &MyData{
|
|
||||||
Name: name,
|
|
||||||
Phone: phone,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MyData) ToString() string {
|
|
||||||
return fmt.Sprintf("Имя: %s, Телефон: %s", d.Name, d.Phone)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintList(list []MyData) {
|
|
||||||
for _, el := range list {
|
|
||||||
fmt.Printf("%s\n", el.ToString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
package data_struct
|
|
||||||
|
|
||||||
func QSort(arr []MyData, l, r int) []MyData {
|
|
||||||
result := make([]MyData, len(arr))
|
|
||||||
copy(result, arr)
|
|
||||||
qSort(result, l, r)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func qSort(arr []MyData, l, r int) []MyData {
|
|
||||||
if l < r {
|
|
||||||
s := Partition_Hoa(arr, l, r)
|
|
||||||
arr = qSort(arr, l, s)
|
|
||||||
arr = qSort(arr, s+1, r)
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
|
|
||||||
func Partition_Hoa(arr []MyData, l, r int) int {
|
|
||||||
p := arr[(l+r)/2].Name
|
|
||||||
i := l - 1
|
|
||||||
j := r + 1
|
|
||||||
|
|
||||||
for {
|
|
||||||
for {
|
|
||||||
i++
|
|
||||||
if arr[i].Name >= p {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
j--
|
|
||||||
if arr[j].Name <= p {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i >= j {
|
|
||||||
return j
|
|
||||||
}
|
|
||||||
|
|
||||||
arr[i], arr[j] = arr[j], arr[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package gen_data
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MAX_USER_IND = 10000
|
|
||||||
PHONE_LEN = 11
|
|
||||||
)
|
|
||||||
|
|
||||||
func genRandomPhone() string {
|
|
||||||
phone := ""
|
|
||||||
for i := 0; i < PHONE_LEN; i++ {
|
|
||||||
phone += fmt.Sprintf("%d", rand.Intn(10))
|
|
||||||
}
|
|
||||||
|
|
||||||
return phone
|
|
||||||
}
|
|
||||||
|
|
||||||
func RecordsShuffled(count int) []ds.MyData {
|
|
||||||
data := make([]ds.MyData, count)
|
|
||||||
number := 0
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
number = rand.Intn(MAX_USER_IND)
|
|
||||||
data[i].Name = fmt.Sprintf("User_%05d", number)
|
|
||||||
data[i].Phone = genRandomPhone()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Перемешиваем (Fisher-Yates shuffle)
|
|
||||||
for i := len(data) - 1; i > 0; i-- {
|
|
||||||
j := rand.Intn(i + 1)
|
|
||||||
data[i], data[j] = data[j], data[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func RecordsSorted(count int) []ds.MyData {
|
|
||||||
data := RecordsShuffled(count)
|
|
||||||
|
|
||||||
data = ds.QSort(data, 0, len(data)-1)
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
@ -1,287 +0,0 @@
|
||||||
package bin_search_tree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BinSearchTree struct {
|
|
||||||
root *BSTree
|
|
||||||
}
|
|
||||||
|
|
||||||
type BSTree struct {
|
|
||||||
data ds.MyData
|
|
||||||
|
|
||||||
left *BSTree
|
|
||||||
right *BSTree
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBinSearchTree() *BinSearchTree {
|
|
||||||
return &BinSearchTree{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBinSearchTree(data ds.MyData) *BSTree {
|
|
||||||
return &BSTree{
|
|
||||||
data: data,
|
|
||||||
left: nil,
|
|
||||||
right: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Len() int {
|
|
||||||
return bst.root.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BSTree) Len() int {
|
|
||||||
if bst == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 1 + bst.left.Len() + bst.right.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Minimum() *BSTree {
|
|
||||||
return bst.root.Minimum()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (root *BSTree) Minimum() *BSTree {
|
|
||||||
if root == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if root.left == nil {
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
return root.left.Minimum()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Maximum() *BSTree {
|
|
||||||
return bst.root.Maximum()
|
|
||||||
}
|
|
||||||
func (root *BSTree) Maximum() *BSTree {
|
|
||||||
if root == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if root.right == nil {
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
return root.right.Maximum()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (node *BSTree) PrintNode() {
|
|
||||||
fmt.Print(node.data.ToString())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (node *BSTree) ToString() string {
|
|
||||||
if node == nil {
|
|
||||||
return "nil"
|
|
||||||
}
|
|
||||||
return node.data.ToString()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) BstInorderTraversal() {
|
|
||||||
bst.root.BstInorderTraversal()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (root *BSTree) BstInorderTraversal() {
|
|
||||||
if root != nil {
|
|
||||||
root.left.BstInorderTraversal()
|
|
||||||
root.PrintNode()
|
|
||||||
fmt.Println()
|
|
||||||
root.right.BstInorderTraversal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) BstPreorderTraversal() {
|
|
||||||
bst.root.BstPreorderTraversal()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (root *BSTree) BstPreorderTraversal() {
|
|
||||||
if root != nil {
|
|
||||||
root.PrintNode()
|
|
||||||
fmt.Println()
|
|
||||||
root.left.BstPreorderTraversal()
|
|
||||||
root.right.BstPreorderTraversal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search
|
|
||||||
// Возвращает номер телефона по имени
|
|
||||||
func (bst *BinSearchTree) Search(targetName string) (string, bool) {
|
|
||||||
node, ok := bst.root.search(targetName)
|
|
||||||
if ok {
|
|
||||||
return node.data.Phone, true
|
|
||||||
}
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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)
|
|
||||||
*/
|
|
||||||
// Приватная вспомогательная функция поиска
|
|
||||||
func (node *BSTree) search(targetName string) (*BSTree, bool) {
|
|
||||||
if node == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
if node.data.Name == targetName {
|
|
||||||
return node, true
|
|
||||||
}
|
|
||||||
if targetName < node.data.Name {
|
|
||||||
return node.left.search(targetName)
|
|
||||||
}
|
|
||||||
return node.right.search(targetName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (node *BinSearchTree) Insert(data ds.MyData) *BinSearchTree {
|
|
||||||
// if node == nil {
|
|
||||||
// return NewBinSearchTree(data)
|
|
||||||
// } else if data.Name < node.data.Name {
|
|
||||||
// node.left = node.left.Insert(data)
|
|
||||||
// } else if data.Name > node.data.Name {
|
|
||||||
// node.right = node.right.Insert(data)
|
|
||||||
// } else {
|
|
||||||
// node.data.Phone = data.Phone // Заменяем существующее значение
|
|
||||||
// }
|
|
||||||
// return node
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Insert(data ds.MyData) {
|
|
||||||
bst.root = bst.root.insert(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (root *BSTree) insert(data ds.MyData) *BSTree {
|
|
||||||
if root == nil {
|
|
||||||
return &BSTree{
|
|
||||||
data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.Name < root.data.Name {
|
|
||||||
root.left = root.left.insert(data)
|
|
||||||
} else if data.Name > root.data.Name {
|
|
||||||
root.right = root.right.insert(data)
|
|
||||||
} else {
|
|
||||||
root.data.Phone = data.Phone
|
|
||||||
}
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) InsertAll(data []ds.MyData) {
|
|
||||||
for _, el := range data {
|
|
||||||
bst.Insert(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete удаляет узел по имени.
|
|
||||||
// Возвращает нового потомка для родительского узла.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Node delete(root : Node, z : T): // корень поддерева, удаляемый ключ
|
|
||||||
if root == null
|
|
||||||
return root
|
|
||||||
if z < root.key
|
|
||||||
root.left = delete(root.left, z)
|
|
||||||
else if z > root.key
|
|
||||||
root.right = delete(root.right, z)
|
|
||||||
else if root.left != null and root.right != null
|
|
||||||
root.key = minimum(root.right).key
|
|
||||||
root.right = delete(root.right, root.key)
|
|
||||||
else
|
|
||||||
if root.left != null
|
|
||||||
root = root.left
|
|
||||||
else if root.right != null
|
|
||||||
root = root.right
|
|
||||||
else
|
|
||||||
root = null
|
|
||||||
return root
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Height() int {
|
|
||||||
if bst.root == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return bst.root.height()
|
|
||||||
}
|
|
||||||
|
|
||||||
// height возвращает высоту поддерева (для BSTree)
|
|
||||||
func (node *BSTree) height() int {
|
|
||||||
if node == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
leftHeight := node.left.height()
|
|
||||||
rightHeight := node.right.height()
|
|
||||||
|
|
||||||
// Высота = 1 (текущий узел) + максимум из высот поддеревьев
|
|
||||||
if leftHeight > rightHeight {
|
|
||||||
return leftHeight + 1
|
|
||||||
}
|
|
||||||
return rightHeight + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) Delete(targetName string) bool {
|
|
||||||
if bst.root == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
_, found := bst.Search(targetName)
|
|
||||||
if !found {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
bst.root = bst.root.delete(targetName)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (root *BSTree) delete(targetName string) *BSTree {
|
|
||||||
if root == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if targetName < root.data.Name {
|
|
||||||
root.left = root.left.delete(targetName)
|
|
||||||
} else if targetName > root.data.Name {
|
|
||||||
root.right = root.right.delete(targetName)
|
|
||||||
} else {
|
|
||||||
// Нашли узел для удаления
|
|
||||||
|
|
||||||
// Случай 1: нет левого потомка
|
|
||||||
if root.left == nil {
|
|
||||||
return root.right
|
|
||||||
}
|
|
||||||
|
|
||||||
// Случай 2: нет правого потомка
|
|
||||||
if root.right == nil {
|
|
||||||
return root.left
|
|
||||||
}
|
|
||||||
|
|
||||||
// Случай 3: оба потомка есть
|
|
||||||
successor := root.right.Minimum()
|
|
||||||
root.data = successor.data // Копируем все данные сразу
|
|
||||||
root.right = root.right.delete(successor.data.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BinSearchTree) PrintAll() {
|
|
||||||
bst.root.printAll(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bst *BSTree) printAll(depth int) {
|
|
||||||
if bst == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bst.right.printAll(depth + 1)
|
|
||||||
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
fmt.Printf("\t")
|
|
||||||
}
|
|
||||||
bst.PrintNode()
|
|
||||||
bst.left.printAll(depth + 1)
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package hash_table
|
|
||||||
|
|
||||||
func GetHashString(str string) int {
|
|
||||||
hash := 0
|
|
||||||
|
|
||||||
for _, ch := range str {
|
|
||||||
hash = (hash << 5) - hash + int(ch)
|
|
||||||
}
|
|
||||||
|
|
||||||
if hash < 0 {
|
|
||||||
hash = -hash
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
package hash_table
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HashTable - хеш-таблица с цепочками
|
|
||||||
type HashTable struct {
|
|
||||||
buckets []*bucket
|
|
||||||
size int
|
|
||||||
capacity int
|
|
||||||
loadFactor float64
|
|
||||||
}
|
|
||||||
|
|
||||||
type bucket struct {
|
|
||||||
head *elementHT
|
|
||||||
}
|
|
||||||
|
|
||||||
type elementHT struct {
|
|
||||||
data ds.MyData
|
|
||||||
next *elementHT
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewHashTable - создает новую хеш-таблицу
|
|
||||||
func NewHashTable(capacity int, loadFactor float64) *HashTable {
|
|
||||||
|
|
||||||
buckets := make([]*bucket, capacity)
|
|
||||||
|
|
||||||
for i := 0; i < capacity; i++ {
|
|
||||||
buckets[i] = &bucket{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &HashTable{
|
|
||||||
buckets: buckets,
|
|
||||||
size: 0,
|
|
||||||
capacity: capacity,
|
|
||||||
loadFactor: loadFactor,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (h HashTable) getIndex(name string) int {
|
|
||||||
// return GetHashString(name) % h.size
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (h HashTable) Add(name string) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (ht *HashTable) GetIndex(name string) int {
|
|
||||||
hash := GetHashString(name)
|
|
||||||
return hash % ht.capacity
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) Len() int {
|
|
||||||
return ht.size
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (ht *HashTable) getIndex(hash int) int {
|
|
||||||
// return hash % ht.capacity
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (h *HashTable) Insert(new ds.MyData) {
|
|
||||||
|
|
||||||
if h.size >= int(float64(h.capacity)*h.loadFactor) {
|
|
||||||
h.resize()
|
|
||||||
}
|
|
||||||
|
|
||||||
ind := h.GetIndex(new.Name)
|
|
||||||
|
|
||||||
buck := h.buckets[ind]
|
|
||||||
|
|
||||||
current := buck.head
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
if current.data.Name == new.Name {
|
|
||||||
current.data.Phone = new.Phone
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
newHead := &elementHT{
|
|
||||||
data: new,
|
|
||||||
next: buck.head,
|
|
||||||
}
|
|
||||||
|
|
||||||
buck.head = newHead
|
|
||||||
h.size++
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) InsertAll(data []ds.MyData) {
|
|
||||||
for _, el := range data {
|
|
||||||
ht.Insert(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HashTable) Search(name string) (phone string, status bool) {
|
|
||||||
ind := h.GetIndex(name)
|
|
||||||
|
|
||||||
buck := h.buckets[ind]
|
|
||||||
|
|
||||||
current := buck.head
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
if current.data.Name == name {
|
|
||||||
return current.data.Phone, true
|
|
||||||
}
|
|
||||||
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
// func pressEnterToContinue() {
|
|
||||||
// fmt.Print("Нажмите Enter для продолжения...")
|
|
||||||
// bufio.NewReader(os.Stdin).ReadBytes('\n')
|
|
||||||
// }
|
|
||||||
|
|
||||||
// resize - увеличивает размер таблицы
|
|
||||||
func (ht *HashTable) resize() {
|
|
||||||
|
|
||||||
// fmt.Printf("Resize table!\n elements: %d(%.3f%%)\n old capacity: %d\n new capacity: %d\n", ht.size, float64(ht.size)/float64(ht.capacity), ht.capacity, 2*ht.capacity)
|
|
||||||
|
|
||||||
// ht.Print()
|
|
||||||
|
|
||||||
// pressEnterToContinue()
|
|
||||||
|
|
||||||
newCapacity := ht.capacity * 2
|
|
||||||
newHT := NewHashTable(newCapacity, ht.loadFactor)
|
|
||||||
|
|
||||||
for _, b := range ht.buckets {
|
|
||||||
current := b.head
|
|
||||||
for current != nil {
|
|
||||||
newHT.Insert(current.data)
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ht.buckets = newHT.buckets
|
|
||||||
ht.capacity = newCapacity
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) Delete(name string) bool {
|
|
||||||
ind := ht.GetIndex(name)
|
|
||||||
|
|
||||||
buck := ht.buckets[ind]
|
|
||||||
|
|
||||||
if buck.head == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if buck.head.data.Name == name {
|
|
||||||
buck.head = buck.head.next
|
|
||||||
ht.size--
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
prev := buck.head
|
|
||||||
current := buck.head.next
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
if current.data.Name == name {
|
|
||||||
prev.next = current.next
|
|
||||||
ht.size--
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
prev = current
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) Contains(name string) bool {
|
|
||||||
_, ok := ht.Search(name)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (elem *elementHT) ToString() string {
|
|
||||||
if elem == nil {
|
|
||||||
return "nil"
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem.data.ToString()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) Print() {
|
|
||||||
for ind := 0; ind < ht.capacity; ind++ {
|
|
||||||
buck := ht.buckets[ind]
|
|
||||||
current := buck.head
|
|
||||||
|
|
||||||
bucketsStr := ""
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
bucketsStr += " --> " + current.ToString()
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
fmt.Printf("[%d]: %s\n", ind, bucketsStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) listAll() []ds.MyData {
|
|
||||||
data := make([]ds.MyData, ht.size)
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
|
|
||||||
for ind := 0; ind < ht.capacity; ind++ {
|
|
||||||
buck := ht.buckets[ind]
|
|
||||||
current := buck.head
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
data[index] = current.data
|
|
||||||
index++
|
|
||||||
// fmt.Println(current.name, current.phone)
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ht *HashTable) ListAll() []ds.MyData {
|
|
||||||
// fmt.Printf("Size: %d, Capacity: %d\n", ht.size, ht.capacity)
|
|
||||||
data := ht.listAll()
|
|
||||||
|
|
||||||
data = ds.QSort(data, 0, len(data)-1)
|
|
||||||
|
|
||||||
// for i, el := range data {
|
|
||||||
// fmt.Printf("[%d]: \"%s\", %d\n", i, el.name, el.phone)
|
|
||||||
// }
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (ht *HashTable) PrintMostPopularnames(phone int) {
|
|
||||||
// // fmt.Printf("Size: %d, Capacity: %d\n", ht.size, ht.capacity)
|
|
||||||
// data := ht.listAll()
|
|
||||||
|
|
||||||
// data = QSortElementsHT(data, 0, len(data)-1)
|
|
||||||
|
|
||||||
// for i := 0; i < phone; i++ {
|
|
||||||
// fmt.Printf("[%d]: %3d : %s\n", i, ht.GetIndex(data[len(data)-i-1].name), data[len(data)-i-1].ToString())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
@ -1,169 +0,0 @@
|
||||||
package linked_list
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Связный список (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) — собирает все записи в список и сортирует (сортировка вынесена отдельно).
|
|
||||||
*/
|
|
||||||
|
|
||||||
type LinkedList struct {
|
|
||||||
head *LList
|
|
||||||
}
|
|
||||||
|
|
||||||
type LList struct {
|
|
||||||
data ds.MyData
|
|
||||||
|
|
||||||
next *LList
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLinkedList() *LinkedList {
|
|
||||||
return &LinkedList{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLinkedList(data ds.MyData) *LList {
|
|
||||||
return &LList{
|
|
||||||
data: data,
|
|
||||||
next: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LList) ToString() string {
|
|
||||||
if ll == nil {
|
|
||||||
return "nil"
|
|
||||||
}
|
|
||||||
return ll.data.ToString()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) Len() int {
|
|
||||||
|
|
||||||
if ll == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
len := 0
|
|
||||||
|
|
||||||
current := ll.head
|
|
||||||
for current != nil {
|
|
||||||
len++
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
return len
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) Insert(data ds.MyData) {
|
|
||||||
newNode := newLinkedList(data)
|
|
||||||
|
|
||||||
if ll.head == nil {
|
|
||||||
ll.head = newNode
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
current := ll.head
|
|
||||||
for current.next != nil {
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
current.next = newNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) InsertAll(data []ds.MyData) {
|
|
||||||
for _, el := range data {
|
|
||||||
ll.Insert(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) Search(targetName string) (string, bool) {
|
|
||||||
current := ll.head
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
if current.data.Name == targetName {
|
|
||||||
return current.data.Phone, true
|
|
||||||
}
|
|
||||||
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) PrintAll() {
|
|
||||||
current := ll.head
|
|
||||||
index := 0
|
|
||||||
|
|
||||||
for current != nil {
|
|
||||||
fmt.Printf("[%d] %s\n", index, current.ToString())
|
|
||||||
index++
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) Delete(targetName string) bool {
|
|
||||||
if ll.head == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Особый случай: удаление головы списка
|
|
||||||
if ll.head.data.Name == targetName {
|
|
||||||
// Сдвигаем данные и указатель
|
|
||||||
*ll.head = *ll.head.next
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Стандартное удаление из середины/конца
|
|
||||||
current := ll.head
|
|
||||||
for current.next != nil {
|
|
||||||
if current.next.data.Name == targetName {
|
|
||||||
current.next = current.next.next
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) listAll() []ds.MyData {
|
|
||||||
current := ll.head
|
|
||||||
|
|
||||||
listLL := make([]ds.MyData, ll.Len())
|
|
||||||
ind := 0
|
|
||||||
for current != nil {
|
|
||||||
listLL[ind] = current.data
|
|
||||||
ind++
|
|
||||||
current = current.next
|
|
||||||
}
|
|
||||||
|
|
||||||
listLL = ds.QSort(listLL, 0, len(listLL)-1)
|
|
||||||
return listLL
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ll *LinkedList) GetByInd(ind int) (ds.MyData, bool) {
|
|
||||||
if ind >= ll.Len() {
|
|
||||||
return ds.MyData{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
current := ll.head
|
|
||||||
for current != nil {
|
|
||||||
if index == ind {
|
|
||||||
return current.data, true
|
|
||||||
}
|
|
||||||
current = current.next
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
|
|
||||||
return ds.MyData{}, false
|
|
||||||
}
|
|
||||||
|
|
@ -1,379 +0,0 @@
|
||||||
Structure,Mode,Operation,Time
|
|
||||||
Связный список,Случайный,Вставка,0.199516
|
|
||||||
Связный список,Случайный,Поиск,0.024629
|
|
||||||
Связный список,Случайный,Удаление,0.014065
|
|
||||||
Связный список,Случайный,Вставка,0.196946
|
|
||||||
Связный список,Случайный,Поиск,0.023807
|
|
||||||
Связный список,Случайный,Удаление,0.013115
|
|
||||||
Связный список,Случайный,Вставка,0.191475
|
|
||||||
Связный список,Случайный,Поиск,0.023083
|
|
||||||
Связный список,Случайный,Удаление,0.014584
|
|
||||||
Связный список,Случайный,Вставка,0.189964
|
|
||||||
Связный список,Случайный,Поиск,0.024014
|
|
||||||
Связный список,Случайный,Удаление,0.014049
|
|
||||||
Связный список,Случайный,Вставка,0.192273
|
|
||||||
Связный список,Случайный,Поиск,0.023643
|
|
||||||
Связный список,Случайный,Удаление,0.013426
|
|
||||||
Связный список,Случайный,Вставка,0.191623
|
|
||||||
Связный список,Случайный,Поиск,0.022900
|
|
||||||
Связный список,Случайный,Удаление,0.014242
|
|
||||||
Связный список,Случайный,Вставка,0.192131
|
|
||||||
Связный список,Случайный,Поиск,0.024910
|
|
||||||
Связный список,Случайный,Удаление,0.013999
|
|
||||||
Связный список,Случайный,Вставка,0.190054
|
|
||||||
Связный список,Случайный,Поиск,0.023244
|
|
||||||
Связный список,Случайный,Удаление,0.014556
|
|
||||||
Связный список,Случайный,Вставка,0.199543
|
|
||||||
Связный список,Случайный,Поиск,0.023660
|
|
||||||
Связный список,Случайный,Удаление,0.015066
|
|
||||||
Связный список,Случайный,Вставка,0.193103
|
|
||||||
Связный список,Случайный,Поиск,0.023620
|
|
||||||
Связный список,Случайный,Удаление,0.014555
|
|
||||||
Связный список,Случайный,Вставка,0.191255
|
|
||||||
Связный список,Случайный,Поиск,0.023310
|
|
||||||
Связный список,Случайный,Удаление,0.014155
|
|
||||||
Связный список,Случайный,Вставка,0.190051
|
|
||||||
Связный список,Случайный,Поиск,0.023622
|
|
||||||
Связный список,Случайный,Удаление,0.014049
|
|
||||||
Связный список,Случайный,Вставка,0.194320
|
|
||||||
Связный список,Случайный,Поиск,0.024634
|
|
||||||
Связный список,Случайный,Удаление,0.014369
|
|
||||||
Связный список,Случайный,Вставка,0.191525
|
|
||||||
Связный список,Случайный,Поиск,0.023547
|
|
||||||
Связный список,Случайный,Удаление,0.014032
|
|
||||||
Связный список,Случайный,Вставка,0.189879
|
|
||||||
Связный список,Случайный,Поиск,0.022658
|
|
||||||
Связный список,Случайный,Удаление,0.014757
|
|
||||||
Связный список,Случайный,Вставка,0.193771
|
|
||||||
Связный список,Случайный,Поиск,0.023675
|
|
||||||
Связный список,Случайный,Удаление,0.014797
|
|
||||||
Связный список,Случайный,Вставка,0.203894
|
|
||||||
Связный список,Случайный,Поиск,0.025087
|
|
||||||
Связный список,Случайный,Удаление,0.014177
|
|
||||||
Связный список,Случайный,Вставка,0.192419
|
|
||||||
Связный список,Случайный,Поиск,0.023327
|
|
||||||
Связный список,Случайный,Удаление,0.014068
|
|
||||||
Связный список,Случайный,Вставка,0.191059
|
|
||||||
Связный список,Случайный,Поиск,0.023409
|
|
||||||
Связный список,Случайный,Удаление,0.013834
|
|
||||||
Связный список,Случайный,Вставка,0.192096
|
|
||||||
Связный список,Случайный,Поиск,0.023889
|
|
||||||
Связный список,Случайный,Удаление,0.015085
|
|
||||||
Связный список,Случайный,Вставка (среднее),0.193345
|
|
||||||
Связный список,Случайный,Поиск (среднее),0.023733
|
|
||||||
Связный список,Случайный,Удаление (среднее),0.014249
|
|
||||||
Связный список,Отсортированный,Вставка,0.193317
|
|
||||||
Связный список,Отсортированный,Поиск,0.033389
|
|
||||||
Связный список,Отсортированный,Удаление,0.023146
|
|
||||||
Связный список,Отсортированный,Вставка,0.190249
|
|
||||||
Связный список,Отсортированный,Поиск,0.032418
|
|
||||||
Связный список,Отсортированный,Удаление,0.023950
|
|
||||||
Связный список,Отсортированный,Вставка,0.193341
|
|
||||||
Связный список,Отсортированный,Поиск,0.033679
|
|
||||||
Связный список,Отсортированный,Удаление,0.024198
|
|
||||||
Связный список,Отсортированный,Вставка,0.192107
|
|
||||||
Связный список,Отсортированный,Поиск,0.035083
|
|
||||||
Связный список,Отсортированный,Удаление,0.031384
|
|
||||||
Связный список,Отсортированный,Вставка,0.196266
|
|
||||||
Связный список,Отсортированный,Поиск,0.033967
|
|
||||||
Связный список,Отсортированный,Удаление,0.023633
|
|
||||||
Связный список,Отсортированный,Вставка,0.193438
|
|
||||||
Связный список,Отсортированный,Поиск,0.033898
|
|
||||||
Связный список,Отсортированный,Удаление,0.022652
|
|
||||||
Связный список,Отсортированный,Вставка,0.192293
|
|
||||||
Связный список,Отсортированный,Поиск,0.033186
|
|
||||||
Связный список,Отсортированный,Удаление,0.024209
|
|
||||||
Связный список,Отсортированный,Вставка,0.193963
|
|
||||||
Связный список,Отсортированный,Поиск,0.041383
|
|
||||||
Связный список,Отсортированный,Удаление,0.027010
|
|
||||||
Связный список,Отсортированный,Вставка,0.191974
|
|
||||||
Связный список,Отсортированный,Поиск,0.033188
|
|
||||||
Связный список,Отсортированный,Удаление,0.024141
|
|
||||||
Связный список,Отсортированный,Вставка,0.193575
|
|
||||||
Связный список,Отсортированный,Поиск,0.034097
|
|
||||||
Связный список,Отсортированный,Удаление,0.023053
|
|
||||||
Связный список,Отсортированный,Вставка,0.195551
|
|
||||||
Связный список,Отсортированный,Поиск,0.033767
|
|
||||||
Связный список,Отсортированный,Удаление,0.023550
|
|
||||||
Связный список,Отсортированный,Вставка,0.193096
|
|
||||||
Связный список,Отсортированный,Поиск,0.034052
|
|
||||||
Связный список,Отсортированный,Удаление,0.023542
|
|
||||||
Связный список,Отсортированный,Вставка,0.192483
|
|
||||||
Связный список,Отсортированный,Поиск,0.033566
|
|
||||||
Связный список,Отсортированный,Удаление,0.023538
|
|
||||||
Связный список,Отсортированный,Вставка,0.191346
|
|
||||||
Связный список,Отсортированный,Поиск,0.033764
|
|
||||||
Связный список,Отсортированный,Удаление,0.023127
|
|
||||||
Связный список,Отсортированный,Вставка,0.191555
|
|
||||||
Связный список,Отсортированный,Поиск,0.033191
|
|
||||||
Связный список,Отсортированный,Удаление,0.024127
|
|
||||||
Связный список,Отсортированный,Вставка,0.190323
|
|
||||||
Связный список,Отсортированный,Поиск,0.033676
|
|
||||||
Связный список,Отсортированный,Удаление,0.023664
|
|
||||||
Связный список,Отсортированный,Вставка,0.192296
|
|
||||||
Связный список,Отсортированный,Поиск,0.032708
|
|
||||||
Связный список,Отсортированный,Удаление,0.024118
|
|
||||||
Связный список,Отсортированный,Вставка,0.204537
|
|
||||||
Связный список,Отсортированный,Поиск,0.041774
|
|
||||||
Связный список,Отсортированный,Удаление,0.026976
|
|
||||||
Связный список,Отсортированный,Вставка,0.193468
|
|
||||||
Связный список,Отсортированный,Поиск,0.033044
|
|
||||||
Связный список,Отсортированный,Удаление,0.023545
|
|
||||||
Связный список,Отсортированный,Вставка,0.204401
|
|
||||||
Связный список,Отсортированный,Поиск,0.035750
|
|
||||||
Связный список,Отсортированный,Удаление,0.026609
|
|
||||||
Связный список,Отсортированный,Вставка (среднее),0.193979
|
|
||||||
Связный список,Отсортированный,Поиск (среднее),0.034479
|
|
||||||
Связный список,Отсортированный,Удаление (среднее),0.024509
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003026
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003299
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003808
|
|
||||||
Хеш таблица,Случайный,Поиск,0.001001
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003292
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004268
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003100
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004619
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004010
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.002825
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004394
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003335
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004183
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.002352
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.004124
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003422
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.002977
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.005030
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003815
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003015
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка,0.003805
|
|
||||||
Хеш таблица,Случайный,Поиск,0.000000
|
|
||||||
Хеш таблица,Случайный,Удаление,0.000000
|
|
||||||
Хеш таблица,Случайный,Вставка (среднее),0.003635
|
|
||||||
Хеш таблица,Случайный,Поиск (среднее),0.000050
|
|
||||||
Хеш таблица,Случайный,Удаление (среднее),0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.002509
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003017
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003126
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.001002
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.002257
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003013
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.001668
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.002519
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003346
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.004243
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.001588
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.001585
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003053
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003009
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003074
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.001185
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003145
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.004152
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.004280
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003098
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.004386
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003416
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.002529
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка,0.003863
|
|
||||||
Хеш таблица,Отсортированный,Поиск,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Удаление,0.000000
|
|
||||||
Хеш таблица,Отсортированный,Вставка (среднее),0.003181
|
|
||||||
Хеш таблица,Отсортированный,Поиск (среднее),0.000109
|
|
||||||
Хеш таблица,Отсортированный,Удаление (среднее),0.000163
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.004532
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001019
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005690
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001004
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005536
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.001001
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.008002
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.007454
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.001012
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.006524
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.004504
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.007206
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.006102
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.007414
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001003
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005723
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001503
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005705
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.001007
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.006501
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001005
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005375
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.001000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.004520
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.001006
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005931
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.001034
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.007446
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000634
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000521
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005628
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000513
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000510
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.005162
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000511
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000512
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка,0.006672
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск,0.000000
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление,0.000549
|
|
||||||
Бинарное дерево поиска,Случайный,Вставка (среднее),0.006081
|
|
||||||
Бинарное дерево поиска,Случайный,Поиск (среднее),0.000336
|
|
||||||
Бинарное дерево поиска,Случайный,Удаление (среднее),0.000481
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.993672
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060430
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.065743
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.984657
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060576
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.067630
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,1.077915
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.064100
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.066554
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.986610
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060386
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.065383
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.976014
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060724
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.066072
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.954288
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.062234
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.067913
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.948662
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.061164
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064309
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.940560
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.058861
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.065901
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.944873
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060448
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.065882
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.928810
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.061107
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064740
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.925909
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060174
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064934
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.926721
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.062980
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.062940
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.932508
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.059849
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064563
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.941225
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.058925
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.062112
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.935714
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.059868
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064928
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.925400
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.060723
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.063271
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.935481
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.059515
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.063816
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.930136
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.057873
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.063642
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.931535
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.059197
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.064474
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка,0.933106
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск,0.062731
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление,0.062908
|
|
||||||
Бинарное дерево поиска,Отсортированный,Вставка (среднее),0.952690
|
|
||||||
Бинарное дерево поиска,Отсортированный,Поиск (среднее),0.060593
|
|
||||||
Бинарное дерево поиска,Отсортированный,Удаление (среднее),0.064886
|
|
||||||
|
|
|
@ -1,288 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
csvwriter "source/pkg/csv_writer"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
dg "source/pkg/gen_data"
|
|
||||||
bst "source/pkg/structures/bin_search_tree"
|
|
||||||
ht "source/pkg/structures/hash_table"
|
|
||||||
ll "source/pkg/structures/linked_list"
|
|
||||||
|
|
||||||
// csv "source/pkg/csv_ri"
|
|
||||||
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
countUsers = 20_000
|
|
||||||
countRepeat = 20
|
|
||||||
countRandomSearch = 1000
|
|
||||||
countNotExitstSearch = 500
|
|
||||||
countDeletes = 1000
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestData struct {
|
|
||||||
Items []ds.MyData // все записи
|
|
||||||
ItemsSorted []ds.MyData // все записи отсортированные
|
|
||||||
Search []ds.MyData // для поиска (существующие и несуществующие)
|
|
||||||
ToDelete []ds.MyData // для удаления
|
|
||||||
UniqueItems []ds.MyData // Уникальные элементы для тестов
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataStructure interface {
|
|
||||||
Insert(data ds.MyData)
|
|
||||||
InsertAll(data []ds.MyData)
|
|
||||||
Search(name string) (string, bool)
|
|
||||||
Delete(name string) bool
|
|
||||||
Len() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Создатели структур
|
|
||||||
type StructureFactory func() DataStructure
|
|
||||||
|
|
||||||
func NewLinkedList() DataStructure {
|
|
||||||
return ll.NewLinkedList()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHashTable() DataStructure {
|
|
||||||
return ht.NewHashTable(256, 0.75)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBinSearchTree() DataStructure {
|
|
||||||
return bst.NewBinSearchTree()
|
|
||||||
}
|
|
||||||
|
|
||||||
func uniqueElements(data []ds.MyData) []ds.MyData {
|
|
||||||
res := make([]ds.MyData, 0, len(data))
|
|
||||||
|
|
||||||
for _, el := range data {
|
|
||||||
isUnique := true
|
|
||||||
for _, resEl := range res {
|
|
||||||
if el == resEl {
|
|
||||||
isUnique = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isUnique {
|
|
||||||
res = append(res, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateTestData() TestData {
|
|
||||||
items := dg.RecordsShuffled(countUsers)
|
|
||||||
// fmt.Println("isSorted:", isSorted(items))
|
|
||||||
itemsSort := ds.QSort(items, 0, len(items)-1)
|
|
||||||
|
|
||||||
uniqueItems := uniqueElements(items)
|
|
||||||
existing := make([]ds.MyData, countRandomSearch)
|
|
||||||
// notExisting := [countNotExitstSearch]ds.MyData{}
|
|
||||||
notExisting := make([]ds.MyData, countNotExitstSearch)
|
|
||||||
toDelete := make([]ds.MyData, countDeletes)
|
|
||||||
|
|
||||||
countUniq := len(uniqueItems)
|
|
||||||
for i := 0; i < countRandomSearch; i++ {
|
|
||||||
// randInd := rand.Intn(countUsers)
|
|
||||||
randInd := rand.Intn(countUniq)
|
|
||||||
existing[i] = uniqueItems[randInd]
|
|
||||||
// fmt.Println(randInd)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < countNotExitstSearch; i++ {
|
|
||||||
// randInd := rand.Intn(countUsers)
|
|
||||||
randInd := rand.Intn(10)
|
|
||||||
name := fmt.Sprintf("User_%d", randInd)
|
|
||||||
notExisting[i] = *ds.NewData(name, "")
|
|
||||||
// fmt.Println(randInd)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, el := range notExisting {
|
|
||||||
existing = append(existing, el)
|
|
||||||
}
|
|
||||||
|
|
||||||
// toDelete = make([]ds.MyData, countDeletes)
|
|
||||||
usedIndices := make(map[int]bool)
|
|
||||||
for i := 0; i < countDeletes; i++ {
|
|
||||||
var randInd int
|
|
||||||
for {
|
|
||||||
randInd = rand.Intn(countUniq)
|
|
||||||
if !usedIndices[randInd] {
|
|
||||||
usedIndices[randInd] = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toDelete[i] = uniqueItems[randInd]
|
|
||||||
}
|
|
||||||
|
|
||||||
return TestData{
|
|
||||||
Items: items,
|
|
||||||
ItemsSorted: itemsSort,
|
|
||||||
Search: existing,
|
|
||||||
ToDelete: toDelete,
|
|
||||||
UniqueItems: uniqueItems,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Тест вставки массива данных (один раз)
|
|
||||||
func testOnesInsert(structure DataStructure, data []ds.MyData) float64 {
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
for _, item := range data {
|
|
||||||
structure.Insert(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Since(start).Seconds()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Тест поиска массива данных (один раз)
|
|
||||||
func testOnesSearch(structure DataStructure, data []ds.MyData) float64 {
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
// flag := true
|
|
||||||
|
|
||||||
for _, item := range data {
|
|
||||||
structure.Search(item.Name)
|
|
||||||
// p, ok := structure.Search(item.Name)
|
|
||||||
|
|
||||||
// if flag {
|
|
||||||
// flag = ((p == item.Phone) == ok)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// fmt.Println(flag)
|
|
||||||
|
|
||||||
return time.Since(start).Seconds()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Тест удаления массива данных (один раз)
|
|
||||||
func testOnesDelete(structure DataStructure, data []ds.MyData) float64 {
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
for _, item := range data {
|
|
||||||
structure.Delete(item.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Since(start).Seconds()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testForData(nameStruct, mode string, factory StructureFactory, data_insert, data_search, data_delete []ds.MyData) {
|
|
||||||
BenchRes := make([]csvwriter.BenchmarkResult, 0, countRepeat*3+3) // Массив строк отчёта
|
|
||||||
|
|
||||||
averageTimeInsert := 0.
|
|
||||||
averageTimeSearch := 0.
|
|
||||||
averageTimeDelete := 0.
|
|
||||||
|
|
||||||
for iteration := 0; iteration < countRepeat; iteration++ {
|
|
||||||
|
|
||||||
structure := factory()
|
|
||||||
|
|
||||||
insertTime := testOnesInsert(structure, data_insert)
|
|
||||||
averageTimeInsert += insertTime
|
|
||||||
|
|
||||||
// Отладочная информация для бинарного дерева (проверка на вырождение)
|
|
||||||
if bst, ok := structure.(*bst.BinSearchTree); ok {
|
|
||||||
fmt.Printf(
|
|
||||||
"Высота дерева: %d, элементов: %d\n",
|
|
||||||
bst.Height(), bst.Len(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Вставка",
|
|
||||||
Time: insertTime,
|
|
||||||
})
|
|
||||||
|
|
||||||
searchTime := testOnesSearch(structure, data_search)
|
|
||||||
averageTimeSearch += searchTime
|
|
||||||
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Поиск",
|
|
||||||
Time: searchTime,
|
|
||||||
})
|
|
||||||
|
|
||||||
deleteTime := testOnesDelete(structure, data_delete)
|
|
||||||
averageTimeDelete += deleteTime
|
|
||||||
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Удаление",
|
|
||||||
Time: deleteTime,
|
|
||||||
})
|
|
||||||
fmt.Printf("%s | Вставка | %s | Время: %f\n", nameStruct, mode, insertTime)
|
|
||||||
fmt.Printf("%s | Поиск | %s | Время: %f\n", nameStruct, mode, searchTime)
|
|
||||||
fmt.Printf("%s | Удаление | %s | Время: %.9f\n", nameStruct, mode, deleteTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
averageTimeInsert /= countRepeat
|
|
||||||
averageTimeSearch /= countRepeat
|
|
||||||
averageTimeDelete /= countRepeat
|
|
||||||
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Вставка (среднее)",
|
|
||||||
Time: averageTimeInsert,
|
|
||||||
})
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Поиск (среднее)",
|
|
||||||
Time: averageTimeSearch,
|
|
||||||
})
|
|
||||||
BenchRes = append(BenchRes, csvwriter.BenchmarkResult{
|
|
||||||
Structure: nameStruct,
|
|
||||||
Mode: mode,
|
|
||||||
Operation: "Удаление (среднее)",
|
|
||||||
Time: averageTimeDelete,
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Printf("%s | Вставка | %s | Время (среднее): %f\n", nameStruct, mode, averageTimeInsert)
|
|
||||||
fmt.Printf("%s | Поиск | %s | Время (среднее): %f\n", nameStruct, mode, averageTimeSearch)
|
|
||||||
fmt.Printf("%s | Удаление | %s | Время (среднее): %f\n", nameStruct, mode, averageTimeDelete)
|
|
||||||
|
|
||||||
csvwriter.AppendRaw(BenchRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isSorted(data []ds.MyData) bool {
|
|
||||||
for i := 0; i < len(data)-1; i++ {
|
|
||||||
if data[i].Name > data[i+1].Name {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test(nameStruct string, factory StructureFactory) {
|
|
||||||
data := GenerateTestData()
|
|
||||||
|
|
||||||
// fmt.Println("items", isSorted(data.Items))
|
|
||||||
// fmt.Println("items sort", isSorted(data.ItemsSorted))
|
|
||||||
|
|
||||||
testForData(nameStruct, "Случайный", factory, data.Items, data.Search, data.ToDelete)
|
|
||||||
|
|
||||||
testForData(nameStruct, "Отсортированный", factory, data.ItemsSorted, data.Search, data.ToDelete)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
csvwriter.CreateEmptyCSV("results", "benchmarks.csv")
|
|
||||||
|
|
||||||
fmt.Println("============= Начало тестов =============")
|
|
||||||
|
|
||||||
Test("Связный список", NewLinkedList)
|
|
||||||
Test("Хеш таблица", NewHashTable)
|
|
||||||
Test("Бинарное дерево поиска", NewBinSearchTree)
|
|
||||||
|
|
||||||
// fmt.Println("User_0001" < "User_00100")
|
|
||||||
// fmt.Println(isSorted(dg.RecordsShuffled(10000)))
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
bst "source/pkg/structures/bin_search_tree"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
countNumbers = 64
|
|
||||||
)
|
|
||||||
|
|
||||||
func pressEnterToContinue() {
|
|
||||||
fmt.Print("Нажмите Enter для продолжения...")
|
|
||||||
bufio.NewReader(os.Stdin).ReadBytes('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
// isInArr проверяет, содержится ли target в срезе arr[:len]
|
|
||||||
func isInArr(arr []int, length int, target int) bool {
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
if arr[i] == target {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("hello world!")
|
|
||||||
|
|
||||||
head := bst.NewBinSearchTree()
|
|
||||||
|
|
||||||
for i := 1; i <= 20; i++ {
|
|
||||||
name := fmt.Sprintf("User_%02d", i)
|
|
||||||
phone := fmt.Sprintf("Phone_%02d", i)
|
|
||||||
head.Insert(*ds.NewData(name, phone))
|
|
||||||
}
|
|
||||||
|
|
||||||
head.BstInorderTraversal()
|
|
||||||
|
|
||||||
head.Delete("User_05")
|
|
||||||
fmt.Println("Удаляем User_05")
|
|
||||||
|
|
||||||
head.BstInorderTraversal()
|
|
||||||
|
|
||||||
fmt.Println(head.Search("User_07"))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
csvwriter "source/pkg/csv_writer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Простой способ
|
|
||||||
results := []csvwriter.BenchmarkResult{
|
|
||||||
{Structure: "HashTable", Mode: "Chaining", Operation: "Insert", Time: 0.001234},
|
|
||||||
{Structure: "LinkedList", Mode: "Singly", Operation: "Search", Time: 0.005678},
|
|
||||||
{Structure: "BSTree", Mode: "Recursive", Operation: "Delete", Time: 0.003456},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := csvwriter.AppendRaw(results); err != nil {
|
|
||||||
fmt.Printf("Ошибка: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
// hash_table "hash-table-task/hash-table"
|
|
||||||
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
ht "source/pkg/structures/hash_table"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
1. Сконструировать и реализовать свою хеш таблицу
|
|
||||||
|
|
||||||
- изначальный размер 8, коэф-т загрузки 0.75
|
|
||||||
|
|
||||||
- Преобразование подаваемого данного в индекс с помощью хеш функции(в ручну) пример: полиномиальный хеш
|
|
||||||
|
|
||||||
- Коллизии обрабатываются методом цепочек, каждая корзина таблицы - список в котором хранятся пары значений key-value
|
|
||||||
|
|
||||||
- При превышении коэф-та загрузки происходит перехеширование таблицы, размер увеличивается вдвое, все пары заново вставляются в таблицу.
|
|
||||||
|
|
||||||
2. Читаем текстовый файл, разбивает на слова, приводим к нижнему регистру, подсчитываем повторения каждого слова: key - слово, value - кол-во повторений
|
|
||||||
|
|
||||||
- На вывод 10 самых встречающихся слов, для каждого слова выводим: ind(hash), key, value
|
|
||||||
- Текст - первая глава, первые три стиха Евгений Онегин
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("hello world")
|
|
||||||
head := ht.NewHashTable(8, 0.75)
|
|
||||||
|
|
||||||
for i := 1; i <= 40; i++ {
|
|
||||||
name := fmt.Sprintf("User_%02d", i)
|
|
||||||
phone := fmt.Sprintf("Phone_%02d", i)
|
|
||||||
head.Insert(*ds.NewData(name, phone))
|
|
||||||
}
|
|
||||||
|
|
||||||
head.Print()
|
|
||||||
|
|
||||||
head.Delete("User_05")
|
|
||||||
fmt.Println("Удаляем User_05")
|
|
||||||
|
|
||||||
head.Print()
|
|
||||||
|
|
||||||
fmt.Println(head.Search("User_07"))
|
|
||||||
|
|
||||||
// Чтение всего файла
|
|
||||||
|
|
||||||
// const filePath = "../data/onegin.txt"
|
|
||||||
// // const filePath = "../data/onegin_full.txt"
|
|
||||||
|
|
||||||
// data, err := os.ReadFile(filePath)
|
|
||||||
// text := string(data)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("Ошибка чтения файла:", err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// fmt.Println(text)
|
|
||||||
|
|
||||||
// text = strings.ToLower(text)
|
|
||||||
|
|
||||||
// // Разбиение на слова (разделители: пробелы и переводы строк)
|
|
||||||
// re := regexp.MustCompile(`[\p{L}\p{N}-]+`)
|
|
||||||
// words := re.FindAllString(text, -1)
|
|
||||||
|
|
||||||
// fmt.Printf("Найдено слов: %d\n", len(words))
|
|
||||||
// for i, word := range words {
|
|
||||||
// fmt.Printf("Слово %d: %s\n", i+1, word)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// hashTable := ht.NewHashTable(8, 0.95)
|
|
||||||
|
|
||||||
// for i, word := range words {
|
|
||||||
// fmt.Printf("%d : %s\n", i, word)
|
|
||||||
// hashTable.Put(word, 1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fmt.Println("\nХеш таблица текста: ")
|
|
||||||
// hashTable.Print()
|
|
||||||
|
|
||||||
// // fmt.Println("Отсортированные ячейки таблицы: ")
|
|
||||||
// // hashTable.PrintSort()
|
|
||||||
|
|
||||||
// fmt.Println("\nСамые часто встречающиеся слова: ")
|
|
||||||
|
|
||||||
// // hashTable.PrintMostPopularWords(10)
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
ds "source/pkg/data_struct"
|
|
||||||
|
|
||||||
// rs "source/pkg/resulter"
|
|
||||||
ll "source/pkg/structures/linked_list"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isInArr(arr []int, length int, target int) bool {
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
if arr[i] == target {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func Razdelitel() {
|
|
||||||
for i := 0; i < 20; i++ {
|
|
||||||
fmt.Print("-")
|
|
||||||
}
|
|
||||||
fmt.Println()
|
|
||||||
}
|
|
||||||
|
|
||||||
func pressEnterToContinue() {
|
|
||||||
fmt.Print("Нажмите Enter для продолжения...")
|
|
||||||
bufio.NewReader(os.Stdin).ReadBytes('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("hello world!")
|
|
||||||
|
|
||||||
head := ll.NewLinkedList()
|
|
||||||
|
|
||||||
for i := 1; i <= 20; i++ {
|
|
||||||
name := fmt.Sprintf("User_%02d", i)
|
|
||||||
phone := fmt.Sprintf("Phone_%02d", i)
|
|
||||||
head.Insert(*ds.NewData(name, phone))
|
|
||||||
}
|
|
||||||
|
|
||||||
head.PrintAll()
|
|
||||||
|
|
||||||
head.Delete("User_05")
|
|
||||||
|
|
||||||
head.PrintAll()
|
|
||||||
|
|
||||||
fmt.Println(head.Search("User_07"))
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user