forked from UNN/2026-rff_mp
Compare commits
No commits in common. "lab2" and "main" have entirely different histories.
262
stepushovgs/.gitignore
vendored
262
stepushovgs/.gitignore
vendored
|
|
@ -1,262 +0,0 @@
|
|||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.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"))
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,221 +0,0 @@
|
|||
Лабиринт,Алгоритм,Время,Посещено клеток,Длина пути
|
||||
maze10x10,BFS,0.0744000026315916,25.0,16.0
|
||||
maze10x10,BFS,0.0757000016164965,25.0,16.0
|
||||
maze10x10,BFS,0.0727000006008893,25.0,16.0
|
||||
maze10x10,BFS,0.0742999982321634,25.0,16.0
|
||||
maze10x10,BFS,0.0537000014446675,25.0,16.0
|
||||
maze10x10,BFS,0.0547000017832033,25.0,16.0
|
||||
maze10x10,BFS,0.0569000003451947,25.0,16.0
|
||||
maze10x10,BFS,0.0665000006847549,25.0,16.0
|
||||
maze10x10,BFS,0.0543999994988553,25.0,16.0
|
||||
maze10x10,BFS,0.0548999996681232,25.0,16.0
|
||||
maze10x10(среднее),BFS,0.063820000650594,25.0,16.0
|
||||
maze50x50,BFS,1.4375999999174385,972.0,176.0
|
||||
maze50x50,BFS,1.698000000033062,972.0,176.0
|
||||
maze50x50,BFS,1.5351000001828652,972.0,176.0
|
||||
maze50x50,BFS,1.5220999994198792,972.0,176.0
|
||||
maze50x50,BFS,1.574800000526011,972.0,176.0
|
||||
maze50x50,BFS,1.4951999983168207,972.0,176.0
|
||||
maze50x50,BFS,1.511999998911051,972.0,176.0
|
||||
maze50x50,BFS,1.5139999995881226,972.0,176.0
|
||||
maze50x50,BFS,1.4908999983163085,972.0,176.0
|
||||
maze50x50,BFS,1.487499997892883,972.0,176.0
|
||||
maze50x50(среднее),BFS,1.526719999310444,972.0,176.0
|
||||
maze100x100,BFS,3.02670000019134,2345.0,197.0
|
||||
maze100x100,BFS,3.52529999872786,2345.0,197.0
|
||||
maze100x100,BFS,3.663800001959317,2345.0,197.0
|
||||
maze100x100,BFS,3.517799999826821,2345.0,197.0
|
||||
maze100x100,BFS,3.506500001094537,2345.0,197.0
|
||||
maze100x100,BFS,3.690400000778027,2345.0,197.0
|
||||
maze100x100,BFS,3.396100000827573,2345.0,197.0
|
||||
maze100x100,BFS,3.629499999078689,2345.0,197.0
|
||||
maze100x100,BFS,3.8606999987678137,2345.0,197.0
|
||||
maze100x100,BFS,3.4976999995706137,2345.0,197.0
|
||||
maze100x100(среднее),BFS,3.531450000082259,2345.0,197.0
|
||||
maze_empty,BFS,8.452400001260685,5328.0,158.0
|
||||
maze_empty,BFS,8.42489999922691,5328.0,158.0
|
||||
maze_empty,BFS,8.638600000267616,5328.0,158.0
|
||||
maze_empty,BFS,8.208700000977842,5328.0,158.0
|
||||
maze_empty,BFS,8.816000001388602,5328.0,158.0
|
||||
maze_empty,BFS,8.447899999737274,5328.0,158.0
|
||||
maze_empty,BFS,8.679799997480586,5328.0,158.0
|
||||
maze_empty,BFS,8.399000002100365,5328.0,158.0
|
||||
maze_empty,BFS,8.234299999458017,5328.0,158.0
|
||||
maze_empty,BFS,8.313599999382859,5328.0,158.0
|
||||
maze_empty(среднее),BFS,8.461520000128075,5328.0,158.0
|
||||
maze_no_path,BFS,1.6376999992644414,1245.0,0.0
|
||||
maze_no_path,BFS,1.7487000004621225,1245.0,0.0
|
||||
maze_no_path,BFS,1.933600000484148,1245.0,0.0
|
||||
maze_no_path,BFS,1.8192999996244907,1245.0,0.0
|
||||
maze_no_path,BFS,1.8314999979338609,1245.0,0.0
|
||||
maze_no_path,BFS,1.9929000009142328,1245.0,0.0
|
||||
maze_no_path,BFS,1.7305000001215376,1245.0,0.0
|
||||
maze_no_path,BFS,1.6904000003705733,1245.0,0.0
|
||||
maze_no_path,BFS,1.6647000011289492,1245.0,0.0
|
||||
maze_no_path,BFS,1.733000000967877,1245.0,0.0
|
||||
maze_no_path(среднее),BFS,1.778230000127223,1245.0,0.0
|
||||
maze10x10,DFS,0.0433999994129408,24.0,16.0
|
||||
maze10x10,DFS,0.0624999993306119,24.0,16.0
|
||||
maze10x10,DFS,0.0682999998389277,24.0,16.0
|
||||
maze10x10,DFS,0.0490999991598073,24.0,16.0
|
||||
maze10x10,DFS,0.0468999969598371,24.0,16.0
|
||||
maze10x10,DFS,0.0467999998363666,24.0,16.0
|
||||
maze10x10,DFS,0.0689000007696449,24.0,16.0
|
||||
maze10x10,DFS,0.0502000002597924,24.0,16.0
|
||||
maze10x10,DFS,0.0493999978061765,24.0,16.0
|
||||
maze10x10,DFS,0.0475000015285331,24.0,16.0
|
||||
maze10x10(среднее),DFS,0.0532999994902638,24.0,16.0
|
||||
maze50x50,DFS,1.184500000817934,920.0,176.0
|
||||
maze50x50,DFS,1.274300000659423,920.0,176.0
|
||||
maze50x50,DFS,1.3567999994847924,920.0,176.0
|
||||
maze50x50,DFS,1.27749999955995,920.0,176.0
|
||||
maze50x50,DFS,1.4292000014393125,920.0,176.0
|
||||
maze50x50,DFS,1.2790999971912242,920.0,176.0
|
||||
maze50x50,DFS,1.329700000496814,920.0,176.0
|
||||
maze50x50,DFS,1.257100000657374,920.0,176.0
|
||||
maze50x50,DFS,1.4220000011846423,920.0,176.0
|
||||
maze50x50,DFS,1.372599999740487,920.0,176.0
|
||||
maze50x50(среднее),DFS,1.3182800001231954,920.0,176.0
|
||||
maze100x100,DFS,3.26380000115023,2609.0,197.0
|
||||
maze100x100,DFS,3.768599999602884,2609.0,197.0
|
||||
maze100x100,DFS,3.677199998492142,2609.0,197.0
|
||||
maze100x100,DFS,3.6672999995062128,2609.0,197.0
|
||||
maze100x100,DFS,3.9711999997962266,2609.0,197.0
|
||||
maze100x100,DFS,3.7203000028966926,2609.0,197.0
|
||||
maze100x100,DFS,3.739499999937834,2609.0,197.0
|
||||
maze100x100,DFS,3.717999999935273,2609.0,197.0
|
||||
maze100x100,DFS,3.63140000263229,2609.0,197.0
|
||||
maze100x100,DFS,3.789499998674728,2609.0,197.0
|
||||
maze100x100(среднее),DFS,3.6946800002624514,2609.0,197.0
|
||||
maze_empty,DFS,5.714499999157852,5328.0,2578.0
|
||||
maze_empty,DFS,5.989400000544265,5328.0,2578.0
|
||||
maze_empty,DFS,5.901900000026217,5328.0,2578.0
|
||||
maze_empty,DFS,5.935400000453228,5328.0,2578.0
|
||||
maze_empty,DFS,5.898100000194972,5328.0,2578.0
|
||||
maze_empty,DFS,6.119699999544537,5328.0,2578.0
|
||||
maze_empty,DFS,5.7996000032289885,5328.0,2578.0
|
||||
maze_empty,DFS,6.074900000385242,5328.0,2578.0
|
||||
maze_empty,DFS,5.99549999969895,5328.0,2578.0
|
||||
maze_empty,DFS,5.661700000928249,5328.0,2578.0
|
||||
maze_empty(среднее),DFS,5.90907000041625,5328.0,2578.0
|
||||
maze_no_path,DFS,2.58909999683965,1245.0,0.0
|
||||
maze_no_path,DFS,1.87980000191601,1245.0,0.0
|
||||
maze_no_path,DFS,1.6818000003695488,1245.0,0.0
|
||||
maze_no_path,DFS,1.8071000013151208,1245.0,0.0
|
||||
maze_no_path,DFS,1.6453999996883797,1245.0,0.0
|
||||
maze_no_path,DFS,1.7989999978453852,1245.0,0.0
|
||||
maze_no_path,DFS,1.778600002580788,1245.0,0.0
|
||||
maze_no_path,DFS,1.668100001552375,1245.0,0.0
|
||||
maze_no_path,DFS,1.6705999987607356,1245.0,0.0
|
||||
maze_no_path,DFS,1.7055999996955509,1245.0,0.0
|
||||
maze_no_path(среднее),DFS,1.8225100000563543,1245.0,0.0
|
||||
maze10x10,A*,0.0639999998384155,24.0,16.0
|
||||
maze10x10,A*,0.0728000013623386,24.0,16.0
|
||||
maze10x10,A*,0.0684000006003771,24.0,16.0
|
||||
maze10x10,A*,0.0645000000076834,24.0,16.0
|
||||
maze10x10,A*,0.0641000005998648,24.0,16.0
|
||||
maze10x10,A*,0.0661000012769363,24.0,16.0
|
||||
maze10x10,A*,0.0680000011925585,24.0,16.0
|
||||
maze10x10,A*,0.0658999997540377,24.0,16.0
|
||||
maze10x10,A*,0.0686999992467463,24.0,16.0
|
||||
maze10x10,A*,0.0715000023774337,24.0,16.0
|
||||
maze10x10(среднее),A*,0.0674000006256392,24.0,16.0
|
||||
maze50x50,A*,1.6070000019681174,763.0,176.0
|
||||
maze50x50,A*,1.840099997934885,763.0,176.0
|
||||
maze50x50,A*,1.7380999997840263,763.0,176.0
|
||||
maze50x50,A*,1.808999997592764,763.0,176.0
|
||||
maze50x50,A*,1.6594000007899012,763.0,176.0
|
||||
maze50x50,A*,1.821499998186482,763.0,176.0
|
||||
maze50x50,A*,1.6746000001148786,763.0,176.0
|
||||
maze50x50,A*,2.4415000007138588,763.0,176.0
|
||||
maze50x50,A*,2.8442000002542045,763.0,176.0
|
||||
maze50x50,A*,1.8294000001333188,763.0,176.0
|
||||
maze50x50(среднее),A*,1.926479999747244,763.0,176.0
|
||||
maze100x100,A*,2.5787000013224315,1194.0,197.0
|
||||
maze100x100,A*,2.7651999989757314,1194.0,197.0
|
||||
maze100x100,A*,2.860200002032798,1194.0,197.0
|
||||
maze100x100,A*,2.8369999999995343,1194.0,197.0
|
||||
maze100x100,A*,2.906600002461346,1194.0,197.0
|
||||
maze100x100,A*,2.7929999996558763,1194.0,197.0
|
||||
maze100x100,A*,3.06319999799598,1194.0,197.0
|
||||
maze100x100,A*,2.834499999153195,1194.0,197.0
|
||||
maze100x100,A*,2.7511999978742097,1194.0,197.0
|
||||
maze100x100,A*,2.793700001348043,1194.0,197.0
|
||||
maze100x100(среднее),A*,2.8183300000819145,1194.0,197.0
|
||||
maze_empty,A*,13.580099999671802,5328.0,158.0
|
||||
maze_empty,A*,13.65030000306433,5328.0,158.0
|
||||
maze_empty,A*,13.666799997736234,5328.0,158.0
|
||||
maze_empty,A*,14.009900001838105,5328.0,158.0
|
||||
maze_empty,A*,13.549700001021847,5328.0,158.0
|
||||
maze_empty,A*,13.690499999938766,5328.0,158.0
|
||||
maze_empty,A*,13.920800000050804,5328.0,158.0
|
||||
maze_empty,A*,13.680399999429936,5328.0,158.0
|
||||
maze_empty,A*,13.70409999799449,5328.0,158.0
|
||||
maze_empty,A*,13.471199999912642,5328.0,158.0
|
||||
maze_empty(среднее),A*,13.692380000065896,5328.0,158.0
|
||||
maze_no_path,A*,2.5481999982730485,1245.0,0.0
|
||||
maze_no_path,A*,2.8395000008458737,1245.0,0.0
|
||||
maze_no_path,A*,2.7317999993101694,1245.0,0.0
|
||||
maze_no_path,A*,2.7791000029537827,1245.0,0.0
|
||||
maze_no_path,A*,2.718199997616466,1245.0,0.0
|
||||
maze_no_path,A*,2.6510000025155023,1245.0,0.0
|
||||
maze_no_path,A*,2.674000003025867,1245.0,0.0
|
||||
maze_no_path,A*,2.6954999993904494,1245.0,0.0
|
||||
maze_no_path,A*,2.705599999899277,1245.0,0.0
|
||||
maze_no_path,A*,2.7092999989690725,1245.0,0.0
|
||||
maze_no_path(среднее),A*,2.705220000279951,1245.0,0.0
|
||||
maze10x10,Dijkstra,0.0546999981452245,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0766999983170535,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564999972993973,25.0,16.0
|
||||
maze10x10,Dijkstra,0.055399999837391,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0901999992493074,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0636000004305969,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0642000013613142,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0633000017842277,25.0,16.0
|
||||
maze10x10,Dijkstra,0.1010999985737726,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564000001759268,25.0,16.0
|
||||
maze10x10(среднее),Dijkstra,0.0682099995174212,25.0,16.0
|
||||
maze50x50,Dijkstra,1.7924999992828816,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7590999996173196,972.0,176.0
|
||||
maze50x50,Dijkstra,1.8786000000545755,972.0,176.0
|
||||
maze50x50,Dijkstra,1.80720000207657,972.0,176.0
|
||||
maze50x50,Dijkstra,1.840500000980683,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7653000031714328,972.0,176.0
|
||||
maze50x50,Dijkstra,1.9654999996419065,972.0,176.0
|
||||
maze50x50,Dijkstra,1.79049999860581,972.0,176.0
|
||||
maze50x50,Dijkstra,1.797400000214111,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7621000006329268,972.0,176.0
|
||||
maze50x50(среднее),Dijkstra,1.8158700004278217,972.0,176.0
|
||||
maze100x100,Dijkstra,3.954100000555627,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.249900001013884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.330399999162182,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.545499999949243,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.328899998654379,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.53189999825554,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.320200001529884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.45179999951506,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.341399999248097,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.510700000537327,2345.0,197.0
|
||||
maze100x100(среднее),Dijkstra,4.356479999842122,2345.0,197.0
|
||||
maze_empty,Dijkstra,11.241200001677498,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.333599999488795,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.416299999837063,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.310300000332065,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.522700002387865,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.251799998717615,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.823299999377925,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.53350000095088,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.488299998745788,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.370600001100684,5328.0,158.0
|
||||
maze_empty(среднее),Dijkstra,11.429160000261618,5328.0,158.0
|
||||
maze_no_path,Dijkstra,2.119600001606159,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.07120000050054,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.1706000006815884,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.152000000933185,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.309299998159986,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.229900001111673,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.0933000014338177,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.175500001612818,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.386500000284286,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.2796000012021977,1245.0,0.0
|
||||
maze_no_path(среднее),Dijkstra,2.198750000752625,1245.0,0.0
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -1,183 +0,0 @@
|
|||
## Описание работы
|
||||
Схема реализованных классов:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TextFileMazeBuilder {
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
class Maze {
|
||||
-cells: Cell[]
|
||||
-width: int
|
||||
-height: int
|
||||
-start: Cell
|
||||
-exit: Cell
|
||||
+getCell(x,y): Cell
|
||||
+getNeighbors(cell): List~Cell~
|
||||
}
|
||||
|
||||
class Cell {
|
||||
-x: int
|
||||
-y: int
|
||||
-isWall: bool
|
||||
-isStart: bool
|
||||
-isExit: bool
|
||||
-value: int
|
||||
+isPassable(): bool
|
||||
+getXY(): tuple[int, int]
|
||||
+toStr(): str
|
||||
}
|
||||
|
||||
class MazeBuilder {
|
||||
<<interface>>
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
|
||||
class PathFindingStrategy {
|
||||
<<interface>>
|
||||
+name(): str
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class BFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class DFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class AStar {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
+heuristic(a, b): int
|
||||
}
|
||||
class Dijkstra {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class SearchStats {
|
||||
-timeMs: float
|
||||
-visitedCells: int
|
||||
-pathLength: int
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
class MazeSolver {
|
||||
-Maze maze
|
||||
-PathFindingStrategy strategy
|
||||
-Observer observer
|
||||
+strategyName: str
|
||||
+setStrategy(strategy)
|
||||
+solve(): SearchStats
|
||||
}
|
||||
|
||||
class Observer {
|
||||
<<interface>>
|
||||
+update(event)
|
||||
}
|
||||
|
||||
class ConsoleView {
|
||||
+update(event)
|
||||
+render(maze, player_position, path)
|
||||
}
|
||||
|
||||
class Event {
|
||||
-event: str
|
||||
-maze: Maze
|
||||
-player_position: tuple[int,int]
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
MazeBuilder <|.. TextFileMazeBuilder
|
||||
MazeBuilder --> Maze : creates
|
||||
PathFindingStrategy <|.. BFS
|
||||
PathFindingStrategy <|.. DFS
|
||||
PathFindingStrategy <|.. AStar
|
||||
PathFindingStrategy <|.. Dijkstra
|
||||
MazeSolver --> PathFindingStrategy : uses
|
||||
MazeSolver --> Maze : uses
|
||||
Maze --> Cell : uses
|
||||
MazeSolver --> SearchStats : return
|
||||
Observer <|.. ConsoleView
|
||||
ConsoleView --> Event : get
|
||||
MazeSolver --> Observer : notifies
|
||||
```
|
||||
1. Листинги ключевых классов (можно выборочно) или ссылка на репозиторий.
|
||||
- Классы `Cell` и `Maze` представлены в папке `source/classes/`
|
||||
- Реализации интерфейса `Builder` и класса `TextFileMazeBuilder` находятся в `source/builder/`
|
||||
- Реализации интерфейса `Observer` и класса `ConsoleView` находятся в `source/observer/`
|
||||
- Интерфейс `strategy`, класс `MazeSolver` и реализации алгоритмов BFS, DFS, A*, Дейкстра находятся в папке `source/strategy/`
|
||||
## Результаты экспериментов
|
||||
Все результаты находятся в `/data/cvs/banchmark.csv`, тесты запускаются через файл `benchmark.ipynb`. Лабиринты, на которых проходили тесты, находятся в директори `mazes/benchmarks/`
|
||||
Проведём 10 замеров и отобразим результаты на графиках (пунктиром отмечены среднее значение)
|
||||
![[10x10.pdf]]
|
||||
![[50x50.pdf]]
|
||||
![[100x100.pdf]]
|
||||
![[empty.pdf]]
|
||||
![[no_path.pdf]]
|
||||
|
||||
Заполним таблицу для количества посещённых клеток для каждого алгоритма:
|
||||
|
||||
| Лабиринт | BFS | DFS | A* | Дейкстра |
|
||||
| :------------: | :--: | :--: | :--: | :------: |
|
||||
| $10\times10$ | 25 | 24 | 24 | 25 |
|
||||
| $50\times50$ | 972 | 920 | 763 | 972 |
|
||||
| $100\times100$ | 2345 | 2609 | 1194 | 2345 |
|
||||
| Пустой | 5328 | 5328 | 5328 | 5328 |
|
||||
| Без выхода | 1245 | 1245 | 1245 | 1245
|
||||
|
||||
## Анализ результатов
|
||||
- **DFS** быстрее на большинстве лабиринтов, но путь может быть неоптимальным
|
||||
В качестве демонстрации, сравним работу DFS и BFS на небольшом пустом лабиринте:
|
||||
```
|
||||
BFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.8261000002676155 ms
|
||||
visited cells: 315
|
||||
path length: 43
|
||||
```
|
||||
```
|
||||
DFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S..................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#...................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.6825999989814591 ms
|
||||
visited cells: 315
|
||||
path length: 179
|
||||
```
|
||||
Как видно по примеру DFS нашёл путь быстрее (0.68 против 0.82 мс), но длина найденного маршрута 179 клеток, в то время как путь, найденный BFS состоит из 43 клеток.
|
||||
#### A*:
|
||||
- По таблице видно, что A* проходит меньше всего клеток. Это происходит, так как идея алгоритма в том что он отдаёт приоритет клеткам, которые ближе к цели.
|
||||
- На практике медленнее DFS из-за операций с кучей (O(log n) на каждый шаг)
|
||||
|
||||
#### Dijkstra:
|
||||
- По сложности аналогичен BFS для лабиринтов без весов, но медленнее BFS из-за приоритетной очереди.
|
||||
- Имеет смысл на взвешенных графах
|
||||
|
||||
## Выводы
|
||||
Использование ООП и паттернов дало:
|
||||
- расширяемость - лёгкость добавления нового алгоритма поиска без изменения текущей структуры и существующих классов
|
||||
- гибкость - можно менять алгоритмы поиска, конструкторы лабиринтов и способы отображения так же без изменения уже существующих
|
||||
- Лёгкость тестирования - можно тестировать каждый элемент независимо
|
||||
Без этого было бы сложно внедрять новые реализации классов, способы отображения или создания лабиринта или изменять существующие алгоритмы.
|
||||
Но реализация интерфейсов и унификация классов увеличили объём кода и так же наложили ограничения на обрабатываемые данные.
|
||||
|
||||
По скорости лучшим по большинству тестов стал DFS. Второй по скорости BFS, так же он находит самый короткий путь, но при усложнении лабиринта(увеличении развилок и размера) начинает проигрывать A*.
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ### # # # ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # ##### ###
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
#################################################################################################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#################################################################################################################
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ######### ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # #########
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#####################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#####################################
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#######################
|
||||
# # # # # # #
|
||||
### ### ##### # # # ###
|
||||
# # # # # #
|
||||
# # # ##### ### ##### #
|
||||
# # # # # #
|
||||
##### ### # ######### #
|
||||
# #
|
||||
##### # # ### ####### #
|
||||
# # # # # # #
|
||||
########### # ### ### #
|
||||
# # # # # # # #
|
||||
# ### # # ### # ### ###
|
||||
# # # # # # #
|
||||
# ### ####### # # ### #
|
||||
# # # # #
|
||||
### ####### ### #######
|
||||
# # # #
|
||||
########### # ##### # #
|
||||
# # # # #
|
||||
##### ####### ##### # #
|
||||
# # # #
|
||||
#######################
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #### #
|
||||
# E #
|
||||
####################
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #######
|
||||
# #E #
|
||||
####################
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .builder import *
|
||||
from .classes import *
|
||||
from .observer import *
|
||||
from .strategy import *
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .builder import MazeBuilder
|
||||
from .text_file_maze_builder import TextFileMazeBuilder
|
||||
|
||||
__all__ = ['MazeBuilder', 'TextFileMazeBuilder']
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes.maze import Maze
|
||||
|
||||
class MazeBuilder(ABC):
|
||||
@abstractmethod
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
pass
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
from source.classes.maze import Maze, Cell
|
||||
from .builder import MazeBuilder
|
||||
|
||||
|
||||
class TextFileMazeBuilder(MazeBuilder):
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
"""Получает лабиринт из текстового файла"""
|
||||
with open(filename) as f:
|
||||
data = f.read().splitlines()
|
||||
x, y = 0, 0
|
||||
width = len(data[0])
|
||||
height = len(data)
|
||||
|
||||
cells = [[None] * width for _ in range(height)]
|
||||
|
||||
start, c_exit = None, None
|
||||
|
||||
for line in data:
|
||||
x = 0
|
||||
for c in line.strip():
|
||||
if c == 'S':
|
||||
cells[y][x] = Cell(x, y, isStart=True)
|
||||
start = cells[y][x]
|
||||
x += 1
|
||||
elif c == 'E':
|
||||
cells[y][x] = Cell(x, y, isExit=True)
|
||||
c_exit = cells[y][x]
|
||||
x += 1
|
||||
elif c == '#':
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
elif c == ' ':
|
||||
cells[y][x] = Cell(x, y)
|
||||
x += 1
|
||||
else:
|
||||
print(f'Обнаружен неизвестный символ({c}) в файле лабиринта\nfilename: {filename}\nОн заменён на стену')
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
|
||||
y += 1
|
||||
|
||||
if start == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен вход!\nfilename: {filename}')
|
||||
|
||||
if c_exit == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен выход!\nfilename: {filename}')
|
||||
|
||||
return Maze(
|
||||
cells=cells,
|
||||
width=width,
|
||||
height=height,
|
||||
start=start,
|
||||
exit_cell=c_exit
|
||||
)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .cell import Cell
|
||||
from .maze import Maze
|
||||
|
||||
__all__ = ['Cell', 'Maze']
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
class Cell:
|
||||
"""
|
||||
Клетка лабиринта
|
||||
|
||||
`x, y` - координаты клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
|
||||
def __init__(self, x: int, y: int, isWall=False, isStart=False, isExit=False, value=1):
|
||||
"""
|
||||
Создание клетки лабиринта
|
||||
|
||||
`x` - столбец клетки в лабиринте
|
||||
`y` - строка клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
self.__x = x
|
||||
self.__y = y
|
||||
self.isWall = isWall
|
||||
self.isStart = isStart
|
||||
self.isExit = isExit
|
||||
self.__value = value
|
||||
pass
|
||||
|
||||
@property
|
||||
def isPassable(self) -> bool:
|
||||
"""возвращает `True` для прохода, если клетка не стена"""
|
||||
return not self.isWall
|
||||
|
||||
@property
|
||||
def x(self) -> int:
|
||||
"""Возвращает координату клетки по оси X"""
|
||||
return self.__x
|
||||
|
||||
@property
|
||||
def y(self) -> int:
|
||||
"""Возвращает координату клетки по оси Y"""
|
||||
return self.__y
|
||||
|
||||
def getXY(self) -> tuple[int, int]:
|
||||
"""Возвращает кортеж координат в формате `(x, y)`"""
|
||||
return self.__x, self.__y
|
||||
|
||||
@property
|
||||
def value(self) -> int:
|
||||
"""Возвращает вес клетки"""
|
||||
return self.__value
|
||||
|
||||
def toStr(self) -> str:
|
||||
"""
|
||||
Возвращает строчкое представление клетки
|
||||
|
||||
`#` - Стена
|
||||
|
||||
`S` - Начало лабиринта
|
||||
|
||||
`E` - Конец лабиринта
|
||||
|
||||
` `(пробел) - свободный проход
|
||||
|
||||
`<int>` - Вес клетки
|
||||
"""
|
||||
if self.isWall:
|
||||
return '#'
|
||||
elif self.isStart:
|
||||
return 'S'
|
||||
elif self.isExit:
|
||||
return 'E'
|
||||
else:
|
||||
return ' '
|
||||
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
from .cell import Cell
|
||||
|
||||
class Maze:
|
||||
"""Лабиринт"""
|
||||
def __init__(self, cells, width: int, height: int, start: Cell, exit_cell: Cell):
|
||||
self.cells = cells
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.start = start
|
||||
self.exit = exit_cell
|
||||
pass
|
||||
|
||||
def getCell(self, x: int, y: int) -> Cell:
|
||||
return self.cells[y][x] # строка стобец
|
||||
|
||||
def getNeighbors(self, cell) -> list[Cell]:
|
||||
"""Возвращает список соседних проходимых клеток (вверх, вниз, влево, вправо, если в пределах границ и не стена)."""
|
||||
neighbors = []
|
||||
|
||||
c_x, c_y = cell.getXY()
|
||||
|
||||
if c_y - 1 >= 0 and not self.cells[c_y - 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y - 1][c_x])
|
||||
|
||||
if c_y + 1 < self.height and not self.cells[c_y + 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y + 1][c_x])
|
||||
|
||||
if c_x - 1 >= 0 and not self.cells[c_y][c_x - 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x - 1])
|
||||
|
||||
if c_x + 1 < self.width and not self.cells[c_y][c_x + 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x + 1])
|
||||
|
||||
return neighbors
|
||||
|
||||
def printer(self):
|
||||
"""Выводит в консоль лабиринт (отладочное)"""
|
||||
for line in self.cells:
|
||||
for c in line:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
def info(self):
|
||||
"""Основная информация о лабиринте"""
|
||||
print(f'height: {self.height}\nwidth: {self.width}\nstart: {self.start.getXY()}\nexit: {self.exit.getXY()}\ncount cells: {self.height * self.width}')
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .console_view import ConsoleView
|
||||
from .observer import Observer, Event
|
||||
|
||||
__all__ = ['ConsoleView', 'Observer', 'Event']
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import os
|
||||
|
||||
|
||||
from .observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
class ConsoleView(Observer):
|
||||
|
||||
def update(self, event: Event):
|
||||
"""Вывод состояния лабиринта на экран
|
||||
|
||||
`maze_loaded` - Лабиринт загружен
|
||||
|
||||
`path_found` - Отображает лабиринт и маршрут в нём (символом `*`)
|
||||
|
||||
`move` - Выводит лабиринт и позицию игрока в нём (символом `P`)
|
||||
|
||||
"""
|
||||
if event.event == "path_found":
|
||||
print("Путь найден:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "move":
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "maze_loaded":
|
||||
print("Загружен лабиринт:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def render(self, maze:Maze, player_position: tuple[int, int], path: list):
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
# Если path содержит объекты Cell, преобразуем в координаты
|
||||
if path and isinstance(path[0], Cell):
|
||||
path_xy = [cell.getXY() for cell in path]
|
||||
else:
|
||||
path_xy = path
|
||||
|
||||
# path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
for line in maze.cells:
|
||||
for c in line:
|
||||
if c.getXY() == player_position:
|
||||
print('P', end='')
|
||||
elif c.toStr() in ["S", "E"]:
|
||||
print(c.toStr(), end='')
|
||||
elif c.getXY() in path_xy:
|
||||
print('.', end='')
|
||||
else:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
# def render_xy(self, maze: Maze, player_position: tuple[int, int], path: list[tuple[int, int]]):
|
||||
# os.system('cls' if os.name == 'nt' else 'clear')
|
||||
# # path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
# for line in maze.cells:
|
||||
# for c in line:
|
||||
# if c.getXY() == player_position:
|
||||
# print('P', end='')
|
||||
# elif c.getXY() in path:
|
||||
# print('*', end='')
|
||||
# else:
|
||||
# print(c.toStr(), end='')
|
||||
# print()
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
# import os
|
||||
|
||||
from source.classes import Maze
|
||||
|
||||
|
||||
class Event:
|
||||
def __init__(self, event: str, maze: Maze, player_position: tuple[int, int], path):
|
||||
self.event = event
|
||||
self.maze = maze
|
||||
self.player_position = player_position
|
||||
self.path = path
|
||||
|
||||
|
||||
class Observer(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def update(self, event: Event):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
from collections import deque
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class BFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self):
|
||||
"""Возвращает название метода"""
|
||||
return "BFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
queue = deque([start_cell])
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
queue.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class DFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "DFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
stack = [start_cell]
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while stack:
|
||||
current = stack.pop()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
# new_path = current_path + [neigbour]
|
||||
stack.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class Dijkstra(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "Dijkstra"
|
||||
|
||||
|
||||
def findPath(self, maze: Maze):
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
heappush(queue, (0, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_cost + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
heappush(queue, (new_cost, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from .strategy import PathFindingStrategy, reconstruct_path
|
||||
from .maze_solver import MazeSolver
|
||||
|
||||
|
||||
from .bfs import BFS
|
||||
from .dfs import DFS
|
||||
from .astar import AStar
|
||||
from .dijkstra import Dijkstra
|
||||
# from .maze_solver import MazeSolver
|
||||
# from .strategy import PathFindingStrategy, reconstruct_path
|
||||
|
||||
__all__ = ['BFS', 'DFS', 'AStar', 'Dijkstra', 'MazeSolver', 'PathFindingStrategy', 'reconstruct_path']
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class AStar(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "A*"
|
||||
|
||||
def heuristic(self, a: Cell, b: Cell) -> int:
|
||||
x1, y1 = a.getXY()
|
||||
x2, y2 = b.getXY()
|
||||
|
||||
return abs(x1 - x2) + abs(y1 - y2)
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
start_h = self.heuristic(start_cell, exit_cell)
|
||||
|
||||
heappush(queue, (start_h, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
current_g = cost_visited[current_cell.getXY()]
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_g + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
priority = new_cost + self.heuristic(next_cell, exit_cell)
|
||||
|
||||
heappush(queue, (priority, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import time
|
||||
|
||||
|
||||
from .strategy import PathFindingStrategy
|
||||
from source.observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class MazeSolver:
|
||||
def __init__(self, maze: Maze, strategy: PathFindingStrategy, observer: Observer):
|
||||
self.maze = maze
|
||||
self.strategy = strategy
|
||||
self.observer = observer
|
||||
|
||||
def strategyName(self) -> str:
|
||||
return self.strategy.name
|
||||
|
||||
def setStrategy(self, strategy: PathFindingStrategy):
|
||||
self.strategy = strategy
|
||||
|
||||
def solve(self):
|
||||
start_time = time.perf_counter()
|
||||
path, visited_cells = self.strategy.findPath(self.maze)
|
||||
finish_time = time.perf_counter()
|
||||
|
||||
self.observer.update(Event(
|
||||
event="path_found",
|
||||
maze=self.maze,
|
||||
player_position=self.maze.exit,
|
||||
path=path
|
||||
))
|
||||
|
||||
return SearchStats(
|
||||
timeMs=(finish_time - start_time) * 1000,
|
||||
visitedCells=visited_cells,
|
||||
pathLength=len(path),
|
||||
path=path
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SearchStats:
|
||||
"""Общая информация о тесте алгоритма"""
|
||||
def __init__(self, timeMs: float, visitedCells: int, pathLength: int, path: list[Cell]):
|
||||
self.timeMs = timeMs
|
||||
self.visitedCells = visitedCells
|
||||
self.pathLength = pathLength
|
||||
self.path = path
|
||||
|
||||
def show(self):
|
||||
"""Вывод информации о тесте в консоль"""
|
||||
print(f'time: {self.timeMs} ms\nvisited cells: {self.visitedCells}\npath length: {self.pathLength}')
|
||||
|
||||
# def toStr(self) -> str:
|
||||
# return f'{self.timeMs} {self.visitedCells} {self.pathLength}'
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class PathFindingStrategy(ABC):
|
||||
"""Интерфейс для семейства алгоритмов поиска пути от старта до выхода."""
|
||||
|
||||
@abstractmethod
|
||||
def findPath(self, maze: Maze) -> tuple[list[tuple[int, int]], int]:
|
||||
"""Возвращающим список координат клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток."""
|
||||
pass
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
"""Возвращает название алгоритма"""
|
||||
pass
|
||||
|
||||
# class CellAlgorithm(Cell):
|
||||
# def __init__(self, x: int, y: int, parent: Cell, exitDist: float, isWall=False, isStart=False, isExit=False, value=1):
|
||||
# super().__init__(x, y, isWall, isStart, isExit, value)
|
||||
# self.parent = parent
|
||||
# self.ExitDist = exitDist
|
||||
# self.weight = self.value + exitDist
|
||||
|
||||
|
||||
def reconstruct_path(came_from: dict, start: Cell, end: Cell) -> list[Cell]:
|
||||
"""Восстановление пути по словарю предшественников"""
|
||||
path = []
|
||||
current = end
|
||||
|
||||
# Идём от конца к началу по цепочке came_from
|
||||
while current.getXY() != start.getXY():
|
||||
path.append(current)
|
||||
current = came_from[current.getXY()]
|
||||
|
||||
path.append(start)
|
||||
return path[::-1]
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user