mirror of
https://github.com/koloideal/SortLab.git
synced 2026-06-10 10:25:30 +03:00
update
This commit is contained in:
+156
-5
@@ -1,7 +1,28 @@
|
||||
#include "App.hpp"
|
||||
#include "sorters/BubbleSorter.hpp"
|
||||
#include "sorters/SelectionSorter.hpp"
|
||||
#include "sorters/InsertionSorter.hpp"
|
||||
#include "sorters/MergeSorter.hpp"
|
||||
#include "sorters/QuickSorter.hpp"
|
||||
|
||||
App::App() : window_(sf::VideoMode(1280, 720), "SortLab"), array_(100) {
|
||||
window_.setFramerateLimit(60);
|
||||
App::App()
|
||||
: window_(sf::VideoMode(1280, 720), "SortLab")
|
||||
, array_(100)
|
||||
, currentSorter_(std::make_unique<BubbleSorter>())
|
||||
, ui_()
|
||||
, isPlaying_(false)
|
||||
, timeSinceLastStep_(0.0f)
|
||||
, stepDelay_(0.01f)
|
||||
, isSweeping_(false)
|
||||
, sweepIndex_(0)
|
||||
, sweepTimer_(0.0f)
|
||||
, sweepDelay_(0.005f)
|
||||
, lastComparisons_(0)
|
||||
, lastSwaps_(0) {
|
||||
window_.setFramerateLimit(60);
|
||||
generateBeepSound();
|
||||
beepSound_.setBuffer(beepBuffer_);
|
||||
beepSound_.setVolume(15.0f);
|
||||
}
|
||||
|
||||
void App::run() {
|
||||
@@ -20,14 +41,129 @@ void App::handleEvents() {
|
||||
if (event.type == sf::Event::Closed) {
|
||||
window_.close();
|
||||
}
|
||||
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::R) {
|
||||
array_.shuffle();
|
||||
|
||||
if (event.type == sf::Event::KeyPressed) {
|
||||
switch (event.key.code) {
|
||||
case sf::Keyboard::Space:
|
||||
isPlaying_ = !isPlaying_;
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Right:
|
||||
if (!isPlaying_ && !currentSorter_->isFinished()) {
|
||||
currentSorter_->step(array_);
|
||||
}
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Up:
|
||||
stepDelay_ = (stepDelay_ > 0.001f) ? stepDelay_ * 0.5f : 0.001f;
|
||||
if (stepDelay_ < 0.001f) stepDelay_ = 0.001f;
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Down:
|
||||
stepDelay_ = (stepDelay_ < 0.5f) ? stepDelay_ * 2.0f : 0.5f;
|
||||
if (stepDelay_ > 0.5f) stepDelay_ = 0.5f;
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Num1:
|
||||
switchSorter(std::make_unique<BubbleSorter>());
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Num2:
|
||||
switchSorter(std::make_unique<SelectionSorter>());
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Num3:
|
||||
switchSorter(std::make_unique<InsertionSorter>());
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Num4:
|
||||
switchSorter(std::make_unique<MergeSorter>());
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Num5:
|
||||
switchSorter(std::make_unique<QuickSorter>());
|
||||
break;
|
||||
|
||||
case sf::Keyboard::R:
|
||||
array_.shuffle();
|
||||
array_.resetStates();
|
||||
array_.resetCounters();
|
||||
currentSorter_->reset();
|
||||
isPlaying_ = false;
|
||||
timeSinceLastStep_ = 0.0f;
|
||||
isSweeping_ = false;
|
||||
sweepIndex_ = 0;
|
||||
lastComparisons_ = 0;
|
||||
lastSwaps_ = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void App::update(float dt) {
|
||||
|
||||
ui_.update(*currentSorter_, isPlaying_, currentSorter_->isFinished(), stepDelay_, array_);
|
||||
|
||||
if (isSweeping_) {
|
||||
sweepTimer_ += dt;
|
||||
|
||||
if (sweepTimer_ >= sweepDelay_) {
|
||||
if (sweepIndex_ < array_.getSize()) {
|
||||
array_.setState(sweepIndex_, Array::State::SORTED);
|
||||
|
||||
float normalizedValue = array_.getValue(sweepIndex_) / static_cast<float>(array_.getSize());
|
||||
float pitch = 0.5f + normalizedValue * 1.5f;
|
||||
playBeep(pitch);
|
||||
|
||||
sweepIndex_++;
|
||||
sweepTimer_ = 0.0f;
|
||||
} else {
|
||||
isSweeping_ = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPlaying_ && !currentSorter_->isFinished()) {
|
||||
timeSinceLastStep_ += dt;
|
||||
|
||||
if (timeSinceLastStep_ >= stepDelay_) {
|
||||
size_t beforeComparisons = array_.getComparisons();
|
||||
size_t beforeSwaps = array_.getSwaps();
|
||||
|
||||
currentSorter_->step(array_);
|
||||
|
||||
size_t afterComparisons = array_.getComparisons();
|
||||
size_t afterSwaps = array_.getSwaps();
|
||||
|
||||
if (afterComparisons > beforeComparisons || afterSwaps > beforeSwaps) {
|
||||
float avgPitch = 1.0f;
|
||||
|
||||
for (int i = 0; i < array_.getSize(); ++i) {
|
||||
if (array_.getState(i) == Array::State::COMPARE ||
|
||||
array_.getState(i) == Array::State::SWAP) {
|
||||
float normalizedValue = array_.getValue(i) / static_cast<float>(array_.getSize());
|
||||
avgPitch = 0.5f + normalizedValue * 1.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
playBeep(avgPitch);
|
||||
}
|
||||
|
||||
timeSinceLastStep_ = 0.0f;
|
||||
|
||||
if (currentSorter_->isFinished()) {
|
||||
array_.resetStates();
|
||||
isSweeping_ = true;
|
||||
sweepIndex_ = 0;
|
||||
sweepTimer_ = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void App::render() {
|
||||
@@ -52,5 +188,20 @@ void App::render() {
|
||||
window_.draw(bar);
|
||||
}
|
||||
|
||||
ui_.draw(window_);
|
||||
|
||||
window_.display();
|
||||
}
|
||||
|
||||
void App::switchSorter(std::unique_ptr<Sorter> newSorter) {
|
||||
currentSorter_ = std::move(newSorter);
|
||||
array_.shuffle();
|
||||
array_.resetStates();
|
||||
array_.resetCounters();
|
||||
isPlaying_ = false;
|
||||
timeSinceLastStep_ = 0.0f;
|
||||
isSweeping_ = false;
|
||||
sweepIndex_ = 0;
|
||||
lastComparisons_ = 0;
|
||||
lastSwaps_ = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "App.hpp"
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
void App::generateBeepSound() {
|
||||
const unsigned int sampleRate = 44100;
|
||||
const float duration = 0.02f;
|
||||
const unsigned int sampleCount = static_cast<unsigned int>(sampleRate * duration);
|
||||
|
||||
std::vector<sf::Int16> samples(sampleCount);
|
||||
|
||||
const float frequency = 440.0f;
|
||||
const float amplitude = 3000.0f;
|
||||
|
||||
for (unsigned int i = 0; i < sampleCount; ++i) {
|
||||
float t = static_cast<float>(i) / sampleRate;
|
||||
float envelope = 1.0f - (t / duration);
|
||||
float value = amplitude * envelope * std::sin(2.0f * 3.14159f * frequency * t);
|
||||
samples[i] = static_cast<sf::Int16>(value);
|
||||
}
|
||||
|
||||
beepBuffer_.loadFromSamples(samples.data(), sampleCount, 1, sampleRate);
|
||||
}
|
||||
|
||||
void App::playBeep(float pitch) {
|
||||
if (beepSound_.getStatus() != sf::Sound::Playing) {
|
||||
beepSound_.setPitch(pitch);
|
||||
beepSound_.play();
|
||||
}
|
||||
}
|
||||
+24
-1
@@ -1,6 +1,8 @@
|
||||
#include "Array.hpp"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
|
||||
Array::Array(int size) {
|
||||
Array::Array(int size) : comparisons_(0), swaps_(0) {
|
||||
data_.resize(size);
|
||||
states_.resize(size, State::NORMAL);
|
||||
shuffle();
|
||||
@@ -28,3 +30,24 @@ void Array::setState(int index, State state) { states_[index] = state; }
|
||||
void Array::resetStates() {
|
||||
std::fill(states_.begin(), states_.end(), State::NORMAL);
|
||||
}
|
||||
|
||||
void Array::resetCounters() {
|
||||
comparisons_ = 0;
|
||||
swaps_ = 0;
|
||||
}
|
||||
|
||||
size_t Array::getComparisons() const {
|
||||
return comparisons_;
|
||||
}
|
||||
|
||||
size_t Array::getSwaps() const {
|
||||
return swaps_;
|
||||
}
|
||||
|
||||
void Array::incrementComparisons() {
|
||||
comparisons_++;
|
||||
}
|
||||
|
||||
void Array::incrementSwaps() {
|
||||
swaps_++;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "Sorter.hpp"
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
#include "UI.hpp"
|
||||
#include <iostream>
|
||||
|
||||
UI::UI() : fontLoaded_(false) {
|
||||
if (!font_.loadFromFile("assets/fonts/Roboto-Regular.ttf")) {
|
||||
std::cerr << "Failed to load font" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
fontLoaded_ = true;
|
||||
|
||||
algorithmText_.setFont(font_);
|
||||
algorithmText_.setCharacterSize(24);
|
||||
algorithmText_.setFillColor(sf::Color::White);
|
||||
algorithmText_.setPosition(20.0f, 20.0f);
|
||||
|
||||
stateText_.setFont(font_);
|
||||
stateText_.setCharacterSize(20);
|
||||
stateText_.setFillColor(sf::Color::White);
|
||||
stateText_.setPosition(20.0f, 55.0f);
|
||||
|
||||
comparisonsText_.setFont(font_);
|
||||
comparisonsText_.setCharacterSize(18);
|
||||
comparisonsText_.setFillColor(sf::Color(200, 200, 200));
|
||||
comparisonsText_.setPosition(20.0f, 90.0f);
|
||||
|
||||
swapsText_.setFont(font_);
|
||||
swapsText_.setCharacterSize(18);
|
||||
swapsText_.setFillColor(sf::Color(200, 200, 200));
|
||||
swapsText_.setPosition(20.0f, 115.0f);
|
||||
|
||||
speedText_.setFont(font_);
|
||||
speedText_.setCharacterSize(18);
|
||||
speedText_.setFillColor(sf::Color(200, 200, 200));
|
||||
speedText_.setPosition(20.0f, 140.0f);
|
||||
|
||||
controlsText_.setFont(font_);
|
||||
controlsText_.setCharacterSize(14);
|
||||
controlsText_.setFillColor(sf::Color(150, 150, 150));
|
||||
controlsText_.setPosition(20.0f, 175.0f);
|
||||
controlsText_.setString("[1-5] Algorithms [Space] Play/Pause [Right] Step [Up/Down] Speed [R] Shuffle");
|
||||
}
|
||||
|
||||
void UI::update(const Sorter& sorter, bool isPlaying, bool isFinished, float stepDelay, const Array& array) {
|
||||
if (!fontLoaded_) {
|
||||
return;
|
||||
}
|
||||
|
||||
algorithmText_.setString("Algorithm: " + sorter.getName());
|
||||
|
||||
std::string state;
|
||||
if (isFinished) {
|
||||
state = "Status: Finished";
|
||||
stateText_.setFillColor(sf::Color::Green);
|
||||
} else if (isPlaying) {
|
||||
state = "Status: Playing";
|
||||
stateText_.setFillColor(sf::Color::Yellow);
|
||||
} else {
|
||||
state = "Status: Paused";
|
||||
stateText_.setFillColor(sf::Color::White);
|
||||
}
|
||||
stateText_.setString(state);
|
||||
|
||||
comparisonsText_.setString("Comparisons: " + std::to_string(array.getComparisons()));
|
||||
swapsText_.setString("Swaps: " + std::to_string(array.getSwaps()));
|
||||
|
||||
int delayMs = static_cast<int>(stepDelay * 1000.0f);
|
||||
speedText_.setString("Delay: " + std::to_string(delayMs) + "ms");
|
||||
}
|
||||
|
||||
void UI::draw(sf::RenderWindow& window) {
|
||||
if (!fontLoaded_) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.draw(algorithmText_);
|
||||
window.draw(stateText_);
|
||||
window.draw(comparisonsText_);
|
||||
window.draw(swapsText_);
|
||||
window.draw(speedText_);
|
||||
window.draw(controlsText_);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "sorters/BubbleSorter.hpp"
|
||||
|
||||
BubbleSorter::BubbleSorter()
|
||||
: i_(0), j_(0), n_(0), finished_(false), phase_(Phase::COMPARING) {
|
||||
}
|
||||
|
||||
void BubbleSorter::step(Array& array) {
|
||||
if (finished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_ == 0) {
|
||||
n_ = array.getSize();
|
||||
}
|
||||
|
||||
if (phase_ == Phase::COMPARING) {
|
||||
if (j_ >= n_ - i_ - 1) {
|
||||
i_++;
|
||||
j_ = 0;
|
||||
|
||||
if (i_ >= n_ - 1) {
|
||||
array.resetStates();
|
||||
for (int k = 0; k < n_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
finished_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
array.resetStates();
|
||||
array.setState(j_, Array::State::COMPARE);
|
||||
array.setState(j_ + 1, Array::State::COMPARE);
|
||||
|
||||
array.incrementComparisons();
|
||||
|
||||
if (array.getValue(j_) > array.getValue(j_ + 1)) {
|
||||
phase_ = Phase::SWAPPING;
|
||||
} else {
|
||||
phase_ = Phase::NEXT;
|
||||
}
|
||||
} else if (phase_ == Phase::SWAPPING) {
|
||||
array.setState(j_, Array::State::SWAP);
|
||||
array.setState(j_ + 1, Array::State::SWAP);
|
||||
|
||||
float temp = array.getValue(j_);
|
||||
array.setValue(j_, array.getValue(j_ + 1));
|
||||
array.setValue(j_ + 1, temp);
|
||||
|
||||
array.incrementSwaps();
|
||||
phase_ = Phase::NEXT;
|
||||
} else if (phase_ == Phase::NEXT) {
|
||||
j_++;
|
||||
phase_ = Phase::COMPARING;
|
||||
}
|
||||
}
|
||||
|
||||
bool BubbleSorter::isFinished() const {
|
||||
return finished_;
|
||||
}
|
||||
|
||||
std::string BubbleSorter::getName() const {
|
||||
return "Bubble Sort";
|
||||
}
|
||||
|
||||
void BubbleSorter::reset() {
|
||||
i_ = 0;
|
||||
j_ = 0;
|
||||
n_ = 0;
|
||||
finished_ = false;
|
||||
phase_ = Phase::COMPARING;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "sorters/InsertionSorter.hpp"
|
||||
|
||||
InsertionSorter::InsertionSorter()
|
||||
: i_(1), j_(0), n_(0), key_(0.0f), finished_(false), phase_(Phase::COMPARING) {
|
||||
}
|
||||
|
||||
void InsertionSorter::step(Array& array) {
|
||||
if (finished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_ == 0) {
|
||||
n_ = array.getSize();
|
||||
array.setState(0, Array::State::SORTED);
|
||||
}
|
||||
|
||||
if (phase_ == Phase::COMPARING) {
|
||||
if (i_ >= n_) {
|
||||
array.resetStates();
|
||||
for (int k = 0; k < n_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
finished_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
key_ = array.getValue(i_);
|
||||
j_ = i_ - 1;
|
||||
phase_ = Phase::SHIFTING;
|
||||
} else if (phase_ == Phase::SHIFTING) {
|
||||
if (j_ >= 0) {
|
||||
array.resetStates();
|
||||
array.setState(j_, Array::State::COMPARE);
|
||||
array.setState(j_ + 1, Array::State::SWAP);
|
||||
|
||||
array.incrementComparisons();
|
||||
|
||||
if (array.getValue(j_) > key_) {
|
||||
array.setValue(j_ + 1, array.getValue(j_));
|
||||
array.incrementSwaps();
|
||||
j_--;
|
||||
} else {
|
||||
phase_ = Phase::INSERTING;
|
||||
}
|
||||
} else {
|
||||
phase_ = Phase::INSERTING;
|
||||
}
|
||||
} else if (phase_ == Phase::INSERTING) {
|
||||
array.setValue(j_ + 1, key_);
|
||||
|
||||
for (int k = 0; k <= i_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
|
||||
phase_ = Phase::NEXT;
|
||||
} else if (phase_ == Phase::NEXT) {
|
||||
i_++;
|
||||
phase_ = Phase::COMPARING;
|
||||
}
|
||||
}
|
||||
|
||||
bool InsertionSorter::isFinished() const {
|
||||
return finished_;
|
||||
}
|
||||
|
||||
std::string InsertionSorter::getName() const {
|
||||
return "Insertion Sort";
|
||||
}
|
||||
|
||||
void InsertionSorter::reset() {
|
||||
i_ = 1;
|
||||
j_ = 0;
|
||||
n_ = 0;
|
||||
key_ = 0.0f;
|
||||
finished_ = false;
|
||||
phase_ = Phase::COMPARING;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "sorters/MergeSorter.hpp"
|
||||
|
||||
MergeSorter::MergeSorter()
|
||||
: currentSize_(1), leftStart_(0), mid_(0), rightEnd_(0)
|
||||
, leftIndex_(0), rightIndex_(0), mergeIndex_(0)
|
||||
, finished_(false), phase_(Phase::MERGING), n_(0) {
|
||||
}
|
||||
|
||||
void MergeSorter::step(Array& array) {
|
||||
if (finished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_ == 0) {
|
||||
n_ = array.getSize();
|
||||
temp_.resize(n_);
|
||||
}
|
||||
|
||||
if (currentSize_ >= n_) {
|
||||
array.resetStates();
|
||||
for (int k = 0; k < n_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
finished_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase_ == Phase::MERGING) {
|
||||
if (leftStart_ >= n_ - 1) {
|
||||
currentSize_ *= 2;
|
||||
leftStart_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
mid_ = leftStart_ + currentSize_ - 1;
|
||||
rightEnd_ = (leftStart_ + 2 * currentSize_ - 1 < n_ - 1)
|
||||
? leftStart_ + 2 * currentSize_ - 1
|
||||
: n_ - 1;
|
||||
|
||||
if (mid_ >= n_) {
|
||||
mid_ = n_ - 1;
|
||||
}
|
||||
|
||||
leftIndex_ = leftStart_;
|
||||
rightIndex_ = mid_ + 1;
|
||||
mergeIndex_ = 0;
|
||||
|
||||
for (int k = leftStart_; k <= rightEnd_; ++k) {
|
||||
temp_[mergeIndex_++] = array.getValue(k);
|
||||
}
|
||||
|
||||
leftIndex_ = 0;
|
||||
rightIndex_ = mid_ - leftStart_ + 1;
|
||||
mergeIndex_ = leftStart_;
|
||||
|
||||
phase_ = Phase::COPYING_BACK;
|
||||
} else if (phase_ == Phase::COPYING_BACK) {
|
||||
int leftEnd = mid_ - leftStart_;
|
||||
int rightEndLocal = rightEnd_ - leftStart_;
|
||||
|
||||
if (leftIndex_ <= leftEnd && rightIndex_ <= rightEndLocal) {
|
||||
array.resetStates();
|
||||
array.setState(mergeIndex_, Array::State::SWAP);
|
||||
array.setState(leftStart_ + leftIndex_, Array::State::COMPARE);
|
||||
array.setState(leftStart_ + rightIndex_, Array::State::COMPARE);
|
||||
|
||||
array.incrementComparisons();
|
||||
|
||||
if (temp_[leftIndex_] <= temp_[rightIndex_]) {
|
||||
array.setValue(mergeIndex_, temp_[leftIndex_]);
|
||||
leftIndex_++;
|
||||
} else {
|
||||
array.setValue(mergeIndex_, temp_[rightIndex_]);
|
||||
rightIndex_++;
|
||||
}
|
||||
|
||||
array.incrementSwaps();
|
||||
mergeIndex_++;
|
||||
} else {
|
||||
phase_ = Phase::COPYING_LEFT;
|
||||
}
|
||||
} else if (phase_ == Phase::COPYING_LEFT) {
|
||||
int leftEnd = mid_ - leftStart_;
|
||||
|
||||
if (leftIndex_ <= leftEnd) {
|
||||
array.resetStates();
|
||||
array.setState(mergeIndex_, Array::State::SWAP);
|
||||
|
||||
array.setValue(mergeIndex_, temp_[leftIndex_]);
|
||||
leftIndex_++;
|
||||
mergeIndex_++;
|
||||
array.incrementSwaps();
|
||||
} else {
|
||||
phase_ = Phase::COPYING_RIGHT;
|
||||
}
|
||||
} else if (phase_ == Phase::COPYING_RIGHT) {
|
||||
int rightEndLocal = rightEnd_ - leftStart_;
|
||||
|
||||
if (rightIndex_ <= rightEndLocal) {
|
||||
array.resetStates();
|
||||
array.setState(mergeIndex_, Array::State::SWAP);
|
||||
|
||||
array.setValue(mergeIndex_, temp_[rightIndex_]);
|
||||
rightIndex_++;
|
||||
mergeIndex_++;
|
||||
array.incrementSwaps();
|
||||
} else {
|
||||
phase_ = Phase::NEXT_MERGE;
|
||||
}
|
||||
} else if (phase_ == Phase::NEXT_MERGE) {
|
||||
leftStart_ += 2 * currentSize_;
|
||||
phase_ = Phase::MERGING;
|
||||
}
|
||||
}
|
||||
|
||||
bool MergeSorter::isFinished() const {
|
||||
return finished_;
|
||||
}
|
||||
|
||||
std::string MergeSorter::getName() const {
|
||||
return "Merge Sort";
|
||||
}
|
||||
|
||||
void MergeSorter::reset() {
|
||||
currentSize_ = 1;
|
||||
leftStart_ = 0;
|
||||
mid_ = 0;
|
||||
rightEnd_ = 0;
|
||||
leftIndex_ = 0;
|
||||
rightIndex_ = 0;
|
||||
mergeIndex_ = 0;
|
||||
temp_.clear();
|
||||
finished_ = false;
|
||||
phase_ = Phase::MERGING;
|
||||
n_ = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#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) {
|
||||
}
|
||||
|
||||
void QuickSorter::step(Array& array) {
|
||||
if (finished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_ == 0) {
|
||||
n_ = array.getSize();
|
||||
stack_.push_back({0, n_ - 1});
|
||||
}
|
||||
|
||||
if (stack_.empty()) {
|
||||
array.resetStates();
|
||||
for (int k = 0; k < n_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
finished_ = true;
|
||||
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;
|
||||
}
|
||||
} else if (phase_ == Phase::SWAPPING_PIVOT) {
|
||||
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_) {
|
||||
stack_.push_back({currentLow_, pivotIndex_ - 1});
|
||||
}
|
||||
|
||||
if (pivotIndex_ + 1 < currentHigh_) {
|
||||
stack_.push_back({pivotIndex_ + 1, currentHigh_});
|
||||
}
|
||||
|
||||
j_ = currentLow_;
|
||||
phase_ = Phase::PARTITIONING;
|
||||
}
|
||||
}
|
||||
|
||||
bool QuickSorter::isFinished() const {
|
||||
return finished_;
|
||||
}
|
||||
|
||||
std::string QuickSorter::getName() const {
|
||||
return "Quick Sort";
|
||||
}
|
||||
|
||||
void QuickSorter::reset() {
|
||||
stack_.clear();
|
||||
currentLow_ = 0;
|
||||
currentHigh_ = 0;
|
||||
pivotIndex_ = 0;
|
||||
i_ = 0;
|
||||
j_ = 0;
|
||||
pivotValue_ = 0.0f;
|
||||
finished_ = false;
|
||||
phase_ = Phase::PARTITIONING;
|
||||
n_ = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "sorters/SelectionSorter.hpp"
|
||||
|
||||
SelectionSorter::SelectionSorter()
|
||||
: i_(0), j_(0), minIndex_(0), n_(0), finished_(false), phase_(Phase::FINDING_MIN) {
|
||||
}
|
||||
|
||||
void SelectionSorter::step(Array& array) {
|
||||
if (finished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_ == 0) {
|
||||
n_ = array.getSize();
|
||||
minIndex_ = 0;
|
||||
}
|
||||
|
||||
if (phase_ == Phase::FINDING_MIN) {
|
||||
if (j_ == i_) {
|
||||
minIndex_ = i_;
|
||||
j_++;
|
||||
}
|
||||
|
||||
if (j_ < n_) {
|
||||
array.resetStates();
|
||||
array.setState(i_, Array::State::COMPARE);
|
||||
array.setState(j_, Array::State::COMPARE);
|
||||
array.setState(minIndex_, Array::State::SWAP);
|
||||
|
||||
array.incrementComparisons();
|
||||
|
||||
if (array.getValue(j_) < array.getValue(minIndex_)) {
|
||||
minIndex_ = j_;
|
||||
}
|
||||
|
||||
j_++;
|
||||
} else {
|
||||
phase_ = Phase::SWAPPING;
|
||||
}
|
||||
} else if (phase_ == Phase::SWAPPING) {
|
||||
if (minIndex_ != i_) {
|
||||
array.resetStates();
|
||||
array.setState(i_, Array::State::SWAP);
|
||||
array.setState(minIndex_, Array::State::SWAP);
|
||||
|
||||
float temp = array.getValue(i_);
|
||||
array.setValue(i_, array.getValue(minIndex_));
|
||||
array.setValue(minIndex_, temp);
|
||||
|
||||
array.incrementSwaps();
|
||||
}
|
||||
|
||||
array.setState(i_, Array::State::SORTED);
|
||||
phase_ = Phase::NEXT;
|
||||
} else if (phase_ == Phase::NEXT) {
|
||||
i_++;
|
||||
|
||||
if (i_ >= n_ - 1) {
|
||||
array.resetStates();
|
||||
for (int k = 0; k < n_; ++k) {
|
||||
array.setState(k, Array::State::SORTED);
|
||||
}
|
||||
finished_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
j_ = i_;
|
||||
phase_ = Phase::FINDING_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
bool SelectionSorter::isFinished() const {
|
||||
return finished_;
|
||||
}
|
||||
|
||||
std::string SelectionSorter::getName() const {
|
||||
return "Selection Sort";
|
||||
}
|
||||
|
||||
void SelectionSorter::reset() {
|
||||
i_ = 0;
|
||||
j_ = 0;
|
||||
minIndex_ = 0;
|
||||
n_ = 0;
|
||||
finished_ = false;
|
||||
phase_ = Phase::FINDING_MIN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user