From 9bca5735e855d015fb68800a8e82001bc903ce31 Mon Sep 17 00:00:00 2001 From: kolo Date: Tue, 3 Mar 2026 21:55:57 +0300 Subject: [PATCH] final --- CMakeLists.txt | 56 ++++++---- README.md | 190 ++++++++++++++++++++++++++++++++ assets/app.rc | 1 + assets/icon.ico | Bin 0 -> 4286 bytes assets/icon.png | Bin 0 -> 3662 bytes assets/preview.png | Bin 0 -> 70084 bytes include/sorters/QuickSorter.hpp | 21 +--- src/App.cpp | 7 +- src/sorters/QuickSorter.cpp | 93 +++++++--------- 9 files changed, 278 insertions(+), 90 deletions(-) create mode 100644 assets/app.rc create mode 100644 assets/icon.ico create mode 100644 assets/icon.png create mode 100644 assets/preview.png diff --git a/CMakeLists.txt b/CMakeLists.txt index fd8b3fd..a93d126 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,27 +9,46 @@ FetchContent_Declare( SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG 2.6.x - GIT_SHALLOW ON - EXCLUDE_FROM_ALL - SYSTEM + GIT_SHALLOW ON + EXCLUDE_FROM_ALL + SYSTEM ) FetchContent_MakeAvailable(SFML) -add_executable(SortLab - src/main.cpp - src/App.cpp - src/App_audio.cpp - src/Array.cpp - src/Sorter.cpp - src/UI.cpp - src/OperationsHistory.cpp - src/ProgressMap.cpp - src/sorters/BubbleSorter.cpp - src/sorters/SelectionSorter.cpp - src/sorters/InsertionSorter.cpp - src/sorters/MergeSorter.cpp - src/sorters/QuickSorter.cpp -) +if(WIN32) + add_executable(SortLab + src/main.cpp + src/App.cpp + src/App_audio.cpp + src/Array.cpp + src/Sorter.cpp + src/UI.cpp + src/OperationsHistory.cpp + src/ProgressMap.cpp + src/sorters/BubbleSorter.cpp + src/sorters/SelectionSorter.cpp + src/sorters/InsertionSorter.cpp + src/sorters/MergeSorter.cpp + src/sorters/QuickSorter.cpp + assets/app.rc + ) +else() + add_executable(SortLab + src/main.cpp + src/App.cpp + src/App_audio.cpp + src/Array.cpp + src/Sorter.cpp + src/UI.cpp + src/OperationsHistory.cpp + src/ProgressMap.cpp + src/sorters/BubbleSorter.cpp + src/sorters/SelectionSorter.cpp + src/sorters/InsertionSorter.cpp + src/sorters/MergeSorter.cpp + src/sorters/QuickSorter.cpp + ) +endif() if(MSVC) target_compile_options(SortLab PRIVATE /utf-8) @@ -39,7 +58,6 @@ target_include_directories(SortLab PRIVATE ${CMAKE_SOURCE_DIR}/include) target_link_libraries(SortLab PRIVATE sfml-graphics sfml-window sfml-system sfml-audio) - if(WIN32) add_custom_command(TARGET SortLab POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different diff --git a/README.md b/README.md index e69de29..cacbe95 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,190 @@ +# 🎯 SortLab + +### ⚡ Интерактивный визуализатор алгоритмов сортировки + +![C++](https://img.shields.io/badge/C++-17-00599C?style=flat&logo=cplusplus&logoColor=white) +![SFML](https://img.shields.io/badge/SFML-2.6-8CC445?style=flat&logo=sfml&logoColor=white) +![CMake](https://img.shields.io/badge/CMake-3.16+-064F8C?style=flat&logo=cmake&logoColor=white) +![Platform](https://img.shields.io/badge/Platform-Windows-0078D4?style=flat&logo=windows&logoColor=white) +![License](https://img.shields.io/badge/License-MIT-yellow?style=flat) + +--- + +![SortLab Preview](assets/preview.png) + +--- + +## 📖 О проекте + +**SortLab** — учебный инструмент для наглядного изучения алгоритмов сортировки. +Каждый элемент массива отображается как столбик. Высота = значение. Цвет = состояние. + +Программа показывает работу алгоритма в реальном времени, шаг за шагом, с подсветкой +сравниваемых и переставляемых элементов, счётчиком операций и визуализацией прогресса. + +--- + +## 🧮 Алгоритмы + +| # | Алгоритм | Время (лучшее / среднее / худшее) | Память | +|---|---|---|---| +| `1` | 🫧 Bubble Sort | O(n) / O(n²) / O(n²) | O(1) | +| `2` | 🔍 Selection Sort | O(n²) / O(n²) / O(n²) | O(1) | +| `3` | 🃏 Insertion Sort | O(n) / O(n²) / O(n²) | O(1) | +| `4` | 🔀 Merge Sort | O(n log n) / O(n log n) / O(n log n) | O(n) | +| `5` | ⚡ Quick Sort | O(n log n) / O(n log n) / O(n²) | O(log n) | + +--- + +## 🎮 Управление + +| Клавиша | Действие | +|---|---| +| `Space` | ▶️ Старт / ⏸️ Пауза | +| `R` | 🔀 Перемешать массив | +| `→` | 👣 Один шаг (в режиме паузы) | +| `↑` / `↓` | 🐇 / 🐢 Увеличить / уменьшить скорость | +| `1` — `5` | 🔢 Выбрать алгоритм | +| `I` | ℹ️ Справка о программе | +| `Q` | 🚪 Выход | + +--- + +## 🖥️ Интерфейс + +``` +┌──────────────────────────────────────────────────────────────┐ +│ 📊 Algorithm: Quick Sort Time: O(n log n) Comparisons: 1.2k │ ← UI панель +├────────────────────────────────────┬─────────────────────────┤ +│ │ │ +│ 📈 Столбики массива │ 🗺️ Progress Map │ +│ │ │ +├────────────────────────────────────┴─────────────────────────┤ +│ 📉 Δ Comparisons / step [гистограмма] │ ← нижняя панель +└──────────────────────────────────────────────────────────────┘ +``` + +- 📊 **Главная область** — столбики с цветовой индикацией состояний +- 🗺️ **Progress Map** — миниатюрная сетка всего массива, зеленеет по мере сортировки +- 📉 **Δ Гистограмма** — количество сравнений на каждом шаге (пульс алгоритма) + +### 🎨 Цветовая схема + +| Цвет | Состояние | +|---|---| +| 🔵 Синий | Обычный элемент | +| 🩵 Голубой | Сравниваемые элементы | +| 🟠 Оранжевый | Переставляемые элементы | +| 🟢 Зелёный | Отсортированный элемент | + +--- + +## 🔧 Сборка + +### 📦 Зависимости +- 🛠️ [CMake](https://cmake.org/download/) ≥ 3.16 +- 💻 [Visual Studio 2022](https://visualstudio.microsoft.com/) с компонентом **Desktop development with C++** +- 🌐 Git (для FetchContent — SFML скачивается автоматически) + +### 🚀 Установка + +```bash +git clone https://github.com/your-username/SortLab.git +cd SortLab +cmake -S . -B build +cmake --build build --config Release +.\build\Release\SortLab.exe +``` + +> 💡 SFML 2.6 скачивается и компилируется автоматически при первой сборке. +> ⏱️ Первый запуск `cmake -S . -B build` займёт 1–3 минуты. + +### 🔤 Шрифт +Скачай [JetBrains Mono](https://www.jetbrains.com/lp/mono/) и положи файл в: +``` +assets/fonts/JetBrainsMono-Regular.ttf +``` + +--- + +## 📁 Структура проекта + +``` +SortLab/ +├── 🎨 assets/ +│ ├── fonts/JetBrainsMono-Regular.ttf +│ ├── icon.ico +│ ├── icon.png +│ ├── preview.png +│ └── app.rc +├── 📋 include/ +│ ├── App.hpp +│ ├── Array.hpp +│ ├── Sorter.hpp +│ ├── UI.hpp +│ ├── OperationsHistory.hpp +│ ├── ProgressMap.hpp +│ └── sorters/ +│ ├── BubbleSorter.hpp +│ ├── SelectionSorter.hpp +│ ├── InsertionSorter.hpp +│ ├── MergeSorter.hpp +│ └── QuickSorter.hpp +├── 💻 src/ +│ ├── main.cpp +│ ├── App.cpp +│ ├── App_audio.cpp +│ ├── Array.cpp +│ ├── Sorter.cpp +│ ├── UI.cpp +│ ├── OperationsHistory.cpp +│ ├── ProgressMap.cpp +│ └── sorters/ +│ ├── BubbleSorter.cpp +│ ├── SelectionSorter.cpp +│ ├── InsertionSorter.cpp +│ ├── MergeSorter.cpp +│ └── QuickSorter.cpp +└── ⚙️ CMakeLists.txt +``` + +--- + +## 🏗️ Архитектура + +``` +main() + └── App::run() + ├── handleEvents() — ввод с клавиатуры + ├── update(dt) — шаг сортировки + гистограмма + └── render() + ├── Array bars — основная визуализация + ├── UI overlay — текст, статистика + ├── ProgressMap — мини-карта + └── HistogramRenderer — Δ гистограмма + +Sorter (abstract) + ├── BubbleSorter + ├── SelectionSorter + ├── InsertionSorter + ├── MergeSorter + └── QuickSorter +``` + +> 🔑 Ключевой паттерн: все алгоритмы реализованы как **конечные автоматы** (state machines). +> Метод `step()` выполняет ровно одну атомарную операцию и возвращает управление, +> не блокируя главный поток рендеринга. + +--- + +## 📜 Лицензия + +``` +MIT License — 2026 +``` + +--- + +
+ 🎓 made for college coursework  |  built with ❤️ and C++17 +
diff --git a/assets/app.rc b/assets/app.rc new file mode 100644 index 0000000..a841e99 --- /dev/null +++ b/assets/app.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON "icon.ico" diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c2c888e9440a1e9acb4f5557999cb9f47c377d36 GIT binary patch literal 4286 zcmeH}J4hTs9L8roBZ$F7!4QIkt0W{Uc7irW#0a9K(AsCCXrYCzclK6RHa1#_mA%b1 zrnL-2Y(#vZQNc!3*!;e`8Q3hhTHLuOc;E5cdHiqY+nt@q8sqUxCXKFU^Sv=2j4@w; zD$@n3&x+V$ZH`<;`N{~i!U#;nj6CJN4}OV|cd7l|_>Xfh8j~Pnl=WT|8--v@W%thV z#ni^N4YpHW{VJ8WQ$3mQ&}-=?Z2+kX+TjPdcoTUimIu;RkOtryTwJj|_+(LD@iRDwzc2{W61YBHa$ZrrkHwpTt t7oAW6Wfd?2zE!x3Ogf#&q&zQWMBQT~i2GSmb$$l?EFP&y114dt?>|tV!rlM? literal 0 HcmV?d00001 diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..64f0b9ef16674ec1079e7480cf7a0bed9a101f29 GIT binary patch literal 3662 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 literal 0 HcmV?d00001 diff --git a/include/sorters/QuickSorter.hpp b/include/sorters/QuickSorter.hpp index fb0e1ba..6b6739b 100644 --- a/include/sorters/QuickSorter.hpp +++ b/include/sorters/QuickSorter.hpp @@ -5,30 +5,21 @@ class QuickSorter : public Sorter { public: QuickSorter(); - void step(Array& array) override; bool isFinished() const override; std::string getName() const override; - void reset() override; std::string getTimeComplexity() const override; std::string getSpaceComplexity() const override; + void reset() override; private: + struct Range { int low; int high; }; enum class Phase { PARTITIONING, SWAPPING_PIVOT, PUSHING_RANGES }; - - struct Range { - int low; - int high; - }; - + std::vector stack_; - int currentLow_; - int currentHigh_; - int pivotIndex_; - int i_; - int j_; + Phase phase_; + int currentLow_, currentHigh_, pivotIndex_, i_, j_, n_; float pivotValue_; bool finished_; - Phase phase_; - int n_; + bool needNewRange_; }; diff --git a/src/App.cpp b/src/App.cpp index 9312c25..fd100e5 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -27,7 +27,12 @@ App::App() generateBeepSound(); beepSound_.setBuffer(beepBuffer_); beepSound_.setVolume(100.0f); - + + sf::Image icon; + if (icon.loadFromFile("assets/icon.png")) { + window_.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr()); + } + if (bottomPanelFont_.loadFromFile("assets/fonts/JetBrainsMono-Regular.ttf")) { bottomPanelFontLoaded_ = true; } diff --git a/src/sorters/QuickSorter.cpp b/src/sorters/QuickSorter.cpp index b614379..d2f49b4 100644 --- a/src/sorters/QuickSorter.cpp +++ b/src/sorters/QuickSorter.cpp @@ -1,74 +1,61 @@ #include "sorters/QuickSorter.hpp" -QuickSorter::QuickSorter() - : currentLow_(0), currentHigh_(0), pivotIndex_(0), i_(0), j_(0) - , pivotValue_(0.0f), finished_(false), phase_(Phase::PARTITIONING), n_(0) { +QuickSorter::QuickSorter() { + reset(); } void QuickSorter::step(Array& array) { - if (finished_) { - return; - } - + if (finished_) return; + if (n_ == 0) { n_ = array.getSize(); stack_.push_back({0, n_ - 1}); + needNewRange_ = true; } - - if (stack_.empty()) { - array.resetStates(); - for (int k = 0; k < n_; ++k) { - array.setState(k, Array::State::SORTED); + + if (needNewRange_) { + while (!stack_.empty() && stack_.back().low >= stack_.back().high) { + stack_.pop_back(); } - finished_ = true; + + if (stack_.empty()) { + array.resetStates(); + for (int k = 0; k < n_; ++k) + array.setState(k, Array::State::SORTED); + finished_ = true; + return; + } + + Range range = stack_.back(); + stack_.pop_back(); + currentLow_ = range.low; + currentHigh_ = range.high; + pivotIndex_ = currentHigh_; + pivotValue_ = array.getValue(pivotIndex_); + i_ = currentLow_ - 1; + j_ = currentLow_; + needNewRange_ = false; + phase_ = Phase::PARTITIONING; return; } - + if (phase_ == Phase::PARTITIONING) { - if (j_ == currentLow_) { - Range range = stack_.back(); - stack_.pop_back(); - - if (range.low >= range.high) { - if (stack_.empty()) { - array.resetStates(); - for (int k = 0; k < n_; ++k) { - array.setState(k, Array::State::SORTED); - } - finished_ = true; - } - return; - } - - currentLow_ = range.low; - currentHigh_ = range.high; - pivotIndex_ = currentHigh_; - pivotValue_ = array.getValue(pivotIndex_); - i_ = currentLow_ - 1; - j_ = currentLow_; - } - if (j_ < currentHigh_) { array.resetStates(); array.setState(j_, Array::State::COMPARE); array.setState(pivotIndex_, Array::State::SWAP); - array.incrementComparisons(); - + if (array.getValue(j_) < pivotValue_) { i_++; - if (i_ != j_) { array.setState(i_, Array::State::SWAP); - float temp = array.getValue(i_); array.setValue(i_, array.getValue(j_)); array.setValue(j_, temp); - array.incrementSwaps(); } } - j_++; } else { phase_ = Phase::SWAPPING_PIVOT; @@ -77,26 +64,21 @@ void QuickSorter::step(Array& array) { array.resetStates(); array.setState(i_ + 1, Array::State::SWAP); array.setState(pivotIndex_, Array::State::SWAP); - + float temp = array.getValue(i_ + 1); array.setValue(i_ + 1, array.getValue(pivotIndex_)); array.setValue(pivotIndex_, temp); - array.incrementSwaps(); + pivotIndex_ = i_ + 1; - phase_ = Phase::PUSHING_RANGES; } else if (phase_ == Phase::PUSHING_RANGES) { - if (pivotIndex_ - 1 > currentLow_) { + if (pivotIndex_ - 1 > currentLow_) stack_.push_back({currentLow_, pivotIndex_ - 1}); - } - - if (pivotIndex_ + 1 < currentHigh_) { + if (pivotIndex_ + 1 < currentHigh_) stack_.push_back({pivotIndex_ + 1, currentHigh_}); - } - - j_ = currentLow_; - phase_ = Phase::PARTITIONING; + + needNewRange_ = true; } } @@ -113,7 +95,7 @@ std::string QuickSorter::getTimeComplexity() const { } std::string QuickSorter::getSpaceComplexity() const { - return "O(n)"; + return "O(log n)"; } void QuickSorter::reset() { @@ -125,6 +107,7 @@ void QuickSorter::reset() { j_ = 0; pivotValue_ = 0.0f; finished_ = false; + needNewRange_ = true; phase_ = Phase::PARTITIONING; n_ = 0; }