This commit is contained in:
2026-03-02 15:48:49 +03:00
parent 7cdd2068be
commit d87484393d
21 changed files with 986 additions and 7 deletions
+9 -1
View File
@@ -18,12 +18,20 @@ FetchContent_MakeAvailable(SFML)
add_executable(SortLab add_executable(SortLab
src/main.cpp src/main.cpp
src/App.cpp src/App.cpp
src/App_audio.cpp
src/Array.cpp src/Array.cpp
src/Sorter.cpp
src/UI.cpp
src/sorters/BubbleSorter.cpp
src/sorters/SelectionSorter.cpp
src/sorters/InsertionSorter.cpp
src/sorters/MergeSorter.cpp
src/sorters/QuickSorter.cpp
) )
target_include_directories(SortLab PRIVATE ${CMAKE_SOURCE_DIR}/include) target_include_directories(SortLab PRIVATE ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(SortLab PRIVATE sfml-graphics sfml-window sfml-system) target_link_libraries(SortLab PRIVATE sfml-graphics sfml-window sfml-system sfml-audio)
if(WIN32) if(WIN32)
Binary file not shown.
+23
View File
@@ -1,6 +1,10 @@
#pragma once #pragma once
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <memory>
#include "Array.hpp" #include "Array.hpp"
#include "Sorter.hpp"
#include "UI.hpp"
class App { class App {
public: public:
@@ -11,7 +15,26 @@ private:
void handleEvents(); void handleEvents();
void update(float dt); void update(float dt);
void render(); void render();
void switchSorter(std::unique_ptr<Sorter> newSorter);
void generateBeepSound();
void playBeep(float pitch);
sf::RenderWindow window_; sf::RenderWindow window_;
Array array_; Array array_;
std::unique_ptr<Sorter> currentSorter_;
UI ui_;
bool isPlaying_;
float timeSinceLastStep_;
float stepDelay_;
sf::SoundBuffer beepBuffer_;
sf::Sound beepSound_;
bool isSweeping_;
int sweepIndex_;
float sweepTimer_;
float sweepDelay_;
size_t lastComparisons_;
size_t lastSwaps_;
}; };
+8
View File
@@ -15,8 +15,16 @@ public:
void setValue(int index, float value); void setValue(int index, float value);
void setState(int index, State state); void setState(int index, State state);
void resetStates(); void resetStates();
void resetCounters();
size_t getComparisons() const;
size_t getSwaps() const;
void incrementComparisons();
void incrementSwaps();
private: private:
std::vector<float> data_; std::vector<float> data_;
std::vector<State> states_; std::vector<State> states_;
size_t comparisons_;
size_t swaps_;
}; };
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include "Array.hpp"
#include <string>
class Sorter {
public:
virtual ~Sorter() = default;
virtual void step(Array& array) = 0;
virtual bool isFinished() const = 0;
virtual std::string getName() const = 0;
virtual void reset() = 0;
};
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <SFML/Graphics.hpp>
#include "Sorter.hpp"
#include <string>
class UI {
public:
UI();
void update(const Sorter& sorter, bool isPlaying, bool isFinished, float stepDelay, const Array& array);
void draw(sf::RenderWindow& window);
private:
sf::Font font_;
sf::Text algorithmText_;
sf::Text stateText_;
sf::Text comparisonsText_;
sf::Text swapsText_;
sf::Text speedText_;
sf::Text controlsText_;
bool fontLoaded_;
};
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "Sorter.hpp"
class BubbleSorter : public Sorter {
public:
BubbleSorter();
void step(Array& array) override;
bool isFinished() const override;
std::string getName() const override;
void reset() override;
private:
enum class Phase { COMPARING, SWAPPING, NEXT };
int i_;
int j_;
int n_;
bool finished_;
Phase phase_;
};
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "Sorter.hpp"
class InsertionSorter : public Sorter {
public:
InsertionSorter();
void step(Array& array) override;
bool isFinished() const override;
std::string getName() const override;
void reset() override;
private:
enum class Phase { COMPARING, SHIFTING, INSERTING, NEXT };
int i_;
int j_;
int n_;
float key_;
bool finished_;
Phase phase_;
};
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include "Sorter.hpp"
#include <vector>
class MergeSorter : public Sorter {
public:
MergeSorter();
void step(Array& array) override;
bool isFinished() const override;
std::string getName() const override;
void reset() override;
private:
enum class Phase { MERGING, COPYING_LEFT, COPYING_RIGHT, COPYING_BACK, NEXT_MERGE };
int currentSize_;
int leftStart_;
int mid_;
int rightEnd_;
int leftIndex_;
int rightIndex_;
int mergeIndex_;
std::vector<float> temp_;
bool finished_;
Phase phase_;
int n_;
};
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "Sorter.hpp"
#include <vector>
class QuickSorter : public Sorter {
public:
QuickSorter();
void step(Array& array) override;
bool isFinished() const override;
std::string getName() const override;
void reset() override;
private:
enum class Phase { PARTITIONING, SWAPPING_PIVOT, PUSHING_RANGES };
struct Range {
int low;
int high;
};
std::vector<Range> stack_;
int currentLow_;
int currentHigh_;
int pivotIndex_;
int i_;
int j_;
float pivotValue_;
bool finished_;
Phase phase_;
int n_;
};
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "Sorter.hpp"
class SelectionSorter : public Sorter {
public:
SelectionSorter();
void step(Array& array) override;
bool isFinished() const override;
std::string getName() const override;
void reset() override;
private:
enum class Phase { FINDING_MIN, SWAPPING, NEXT };
int i_;
int j_;
int minIndex_;
int n_;
bool finished_;
Phase phase_;
};
+156 -5
View File
@@ -1,7 +1,28 @@
#include "App.hpp" #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) { App::App()
window_.setFramerateLimit(60); : 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() { void App::run() {
@@ -20,14 +41,129 @@ void App::handleEvents() {
if (event.type == sf::Event::Closed) { if (event.type == sf::Event::Closed) {
window_.close(); 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) { 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() { void App::render() {
@@ -52,5 +188,20 @@ void App::render() {
window_.draw(bar); window_.draw(bar);
} }
ui_.draw(window_);
window_.display(); 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;
}
+30
View File
@@ -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
View File
@@ -1,6 +1,8 @@
#include "Array.hpp" #include "Array.hpp"
#include <random>
#include <algorithm>
Array::Array(int size) { Array::Array(int size) : comparisons_(0), swaps_(0) {
data_.resize(size); data_.resize(size);
states_.resize(size, State::NORMAL); states_.resize(size, State::NORMAL);
shuffle(); shuffle();
@@ -28,3 +30,24 @@ void Array::setState(int index, State state) { states_[index] = state; }
void Array::resetStates() { void Array::resetStates() {
std::fill(states_.begin(), states_.end(), State::NORMAL); 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_++;
}
+1
View File
@@ -0,0 +1 @@
#include "Sorter.hpp"
+82
View File
@@ -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_);
}
+72
View File
@@ -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;
}
+77
View File
@@ -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;
}
+136
View File
@@ -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;
}
+122
View File
@@ -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;
}
+86
View File
@@ -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;
}