Skip to content

Commit 8a7aba3

Browse files
committed
added quick sort
1 parent e07cc9d commit 8a7aba3

7 files changed

Lines changed: 158 additions & 37 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ cloc --include-lang=C++,"C/C++ Header",CMake --exclude-dir=build,vcpkg --out=lin
6565

6666
| Language | Files | Blank | Comment | Code |
6767
|:-----------------|:-----:|:-----:|:-------:|:----:|
68-
| **C++** | 17 | 185 | 78 | 598 |
69-
| **C/C++ Header** | 14 | 131 | 19 | 340 |
68+
| **C++** | 19 | 211 | 94 | 663 |
69+
| **C/C++ Header** | 15 | 138 | 10 | 356 |
7070
| **CMake** | 5 | 29 | 17 | 77 |
7171
| |
72-
| **Total** | 36 | 345 | 114 | 1015 |
72+
| **Total** | 39 | 378 | 121 | 1096 |
7373

7474
</details>

core/include/sorting/SortManager.hpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,17 @@
1111
#include <Bubble.hpp>
1212
#include <Cocktail.hpp>
1313
#include <Insertion.hpp>
14+
#include <Quick.hpp>
1415
#include <Selection.hpp>
15-
// #include <Heap.hpp>
16-
// #include <Merge.hpp>
17-
// #include <Quick.hpp>
18-
// #include <Radix.hpp>
1916

2017
class SortManager {
2118
public:
2219
SortManager() {
23-
// ARRAY OF SORTING ALGORITHMS
24-
initializedCount = 4;
2520
sorts[0] = std::make_unique<Bubble>();
2621
sorts[1] = std::make_unique<Cocktail>();
2722
sorts[2] = std::make_unique<Insertion>();
28-
sorts[3] = std::make_unique<Selection>();
29-
// sorts[4] = std::make_unique<HeapSort>();
30-
// sorts[5] = std::make_unique<MergeSort>();
31-
// sorts[6] = std::make_unique<QuickSort>();
32-
// sorts[7] = std::make_unique<RadixSort>();
23+
sorts[3] = std::make_unique<Quick>();
24+
sorts[4] = std::make_unique<Selection>();
3325
}
3426

3527
const char* GetSortName(int sortId) const;
@@ -49,8 +41,7 @@ class SortManager {
4941
int currentSortId = 0;
5042

5143
private:
52-
int initializedCount = 0;
53-
std::array<std::unique_ptr<Sort>, 8> sorts;
44+
std::array<std::unique_ptr<Sort>, 5> sorts;
5445
std::unique_ptr<SortSequence> sortSequence;
5546
};
5647

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef QUICK_SORT_H
2+
#define QUICK_SORT_H
3+
4+
#include <vector>
5+
#include <memory>
6+
7+
#include <Sort.hpp>
8+
#include <Rect.hpp>
9+
10+
class Quick : public Sort {
11+
public:
12+
const char* GetName() const override { return "Quick"; }
13+
14+
protected:
15+
void RunSort(std::vector<Rect::Rectangle>& array, SortSequence& sequence) override;
16+
17+
private:
18+
void QuickSort(std::vector<Rect::Rectangle>& array, size_t low, size_t high, SortSequence& sequence);
19+
20+
size_t Partition(std::vector<Rect::Rectangle>& array, size_t low, size_t high, SortSequence& sequence);
21+
};
22+
23+
#endif

core/src/app/UserInterface.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ namespace UserInterface {
2929
}
3030

3131
void CreateSortSelectionDropdown(Application::AppContext* appContext) {
32-
float maxWidth = 150.0f;
33-
float availableWidth = ImGui::GetContentRegionAvail().x;
34-
float comboWidth = (availableWidth > maxWidth) ? maxWidth : availableWidth;
35-
ImGui::SetNextItemWidth(comboWidth);
36-
32+
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
3733
int sortId = appContext->sortManager->currentSortId;
3834
if (ImGui::BeginCombo("##Select_Sort", appContext->sortManager->GetSortName(sortId), ImGuiComboFlags_NoArrowButton)) {
3935
int sortCount = appContext->sortManager->GetSortCount();
@@ -51,10 +47,7 @@ namespace UserInterface {
5147
}
5248

5349
void CreateSortSpeedSlider(Application::AppContext* appContext) {
54-
float maxWidth = 150.0f;
55-
float availableWidth = ImGui::GetContentRegionAvail().x;
56-
float sliderWidth = (availableWidth > maxWidth) ? maxWidth : availableWidth;
57-
ImGui::SetNextItemWidth(sliderWidth);
50+
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
5851

5952
// USER ADJUSTED VALUE, DETERMINES SORT SPEED (0 = SLOWEST, 1 = FASTEST)
6053
ImGui::SliderFloat("##SORT_SPEED", &appContext->delayTimeNormalized, 0.0f, 1.0f);
@@ -65,23 +58,21 @@ namespace UserInterface {
6558
int itemCount = 4;
6659
ImGuiStyle& style = ImGui::GetStyle();
6760

68-
float itemHeight = ImGui::GetFrameHeight(); // BASE ITEM HEIGHT
69-
float itemFramePadding = itemCount * (style.FramePadding.y * 2.0f); // TOP/BOTTOM FRAME PADDING
70-
float itemSpacing = (itemCount - 1) * style.ItemSpacing.y; // VERTICAL SPACING BETWEEN ITEMS
71-
float windowPadding = style.WindowPadding.y * 2.0f; // TOP/BOTTOM WINDOW PADDING
72-
float minHeight = windowPadding + itemFramePadding + itemSpacing + (itemCount * itemHeight);
61+
float itemHeight = ImGui::GetFrameHeight(); // BASE ITEM HEIGHT
62+
float itemFramePadding = (itemCount - 0.5) * (style.FramePadding.y * 2.0f); // TOP/BOTTOM FRAME PADDING
63+
float itemSpacing = (itemCount - 1) * style.ItemSpacing.y; // VERTICAL SPACING BETWEEN ITEMS
64+
float minHeight = itemFramePadding + itemSpacing + (itemCount * itemHeight);
7365

74-
float minWidth = 120.0f;
75-
ImVec2 minSize(minWidth, minHeight);
76-
ImVec2 maxSize(minWidth * 2.0f, float(MINIMUM_WINDOW_HEIGHT) / 2.0f);
66+
const float minWidth = float(MINIMUM_WINDOW_WIDTH) / 2.5f;
67+
const ImVec2 minSize(minWidth, minHeight);
7768
ImGui::SetNextWindowSize(minSize, ImGuiCond_FirstUseEver);
78-
ImGui::SetNextWindowSizeConstraints(minSize, maxSize);
79-
ImGui::Begin("##CONTROL_PANEL", nullptr, ImGuiWindowFlags_NoCollapse);
69+
ImGui::SetNextWindowSizeConstraints(minSize, minSize);
70+
ImGui::Begin("##CONTROL_PANEL", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
8071

8172
CreateShuffleButton(appContext);
8273
CreateSortButton(appContext);
83-
CreateSortSelectionDropdown(appContext);
8474
CreateSortSpeedSlider(appContext);
75+
CreateSortSelectionDropdown(appContext);
8576

8677
ImGui::End();
8778
}

core/src/sorting/SortManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const char* SortManager::GetSortName(int sortId) const {
1212
}
1313

1414
int SortManager::GetSortCount() const {
15-
return initializedCount;
15+
return sorts.size();
1616
}
1717

1818
void SortManager::SetSort(int sortId) {

core/src/sorting/sorts/Quick.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include <algorithm>
2+
#include <Quick.hpp>
3+
4+
void Quick::RunSort(std::vector<Rect::Rectangle>& array, SortSequence& sequence) {
5+
if (array.empty()) return;
6+
7+
QuickSort(array, 0, array.size() - 1, sequence);
8+
9+
// ENSURE ALL ELEMENTS ARE MARKED ORDERED
10+
for (auto& rect : array) {
11+
rect.state = Rect::State::ORDERED;
12+
}
13+
}
14+
15+
void Quick::QuickSort(std::vector<Rect::Rectangle>& array, size_t low, size_t high, SortSequence& sequence) {
16+
if (low >= high) {
17+
// HIGHLIGHT ORDERED ELEMENTS
18+
if (low < array.size()) {
19+
array[low].state = Rect::State::ORDERED;
20+
}
21+
return;
22+
}
23+
24+
size_t pivotIndex = Partition(array, low, high, sequence);
25+
if (pivotIndex > 0) {
26+
QuickSort(array, low, pivotIndex - 1, sequence);
27+
}
28+
29+
QuickSort(array, pivotIndex + 1, high, sequence);
30+
}
31+
32+
size_t Quick::Partition(std::vector<Rect::Rectangle>& array, size_t low, size_t high, SortSequence& sequence) {
33+
const int pivotValue = array[high].value;
34+
size_t i = low;
35+
36+
// HIGHLIGHT PIVOT
37+
array[high].state = Rect::State::SELECTED;
38+
PushStep(sequence, array);
39+
40+
for (size_t j = low; j < high; ++j) {
41+
42+
// HIGHLIGHT ELEMENTS BEING GROUPED (VALUE LESS THAN CURRENT PIVOT)
43+
for (size_t k = low; k < i; ++k) {
44+
array[k].state = Rect::State::GROUPING;
45+
}
46+
for (size_t k = i; k < high; ++k) {
47+
if (array[k].state != Rect::State::GROUPING) {
48+
array[k].state = Rect::State::BASE;
49+
}
50+
}
51+
52+
// HIGHLIGHT PIVOT
53+
array[high].state = Rect::State::SELECTED;
54+
55+
// HIGHLIGHT ELEMENT BEING COMPARED
56+
array[j].state = Rect::State::COMPARED;
57+
PushStep(sequence, array);
58+
59+
if (array[j].value < pivotValue) {
60+
std::swap(array[i], array[j]);
61+
62+
// HIGHLIGHT ELEMENTS BEING GROUPED (VALUE LESS THAN CURRENT PIVOT)
63+
array[i].state = Rect::State::GROUPING;
64+
PushStep(sequence, array);
65+
66+
++i;
67+
}
68+
69+
// RESET STATE
70+
array[j].state = Rect::State::BASE;
71+
}
72+
73+
// PLACE PIVOT IN CORRECT POSITION
74+
std::swap(array[i], array[high]);
75+
76+
// RESET STATE
77+
array[high].state = Rect::State::BASE;
78+
array[i].state = Rect::State::ORDERED;
79+
PushStep(sequence, array);
80+
81+
return i;
82+
}

test/src/sorting/sorts/Quick.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <memory>
2+
#include <vector>
3+
4+
#include <gtest/gtest.h>
5+
6+
#include <Quick.hpp>
7+
#include <Sort.hpp>
8+
#include <TestSort.hpp>
9+
10+
TEST(QuickSort_Test, ProducesNonEmptySequence) {
11+
// ARRANGE
12+
Quick sort;
13+
14+
// ACT
15+
SortSequence sequence = TestSort::GenerateSequence(&sort);
16+
17+
// ASSERT
18+
EXPECT_GT(sequence.stepCount, 0);
19+
}
20+
21+
TEST(QuickSort_Test, FinalStepIsSorted) {
22+
// ARRANGE
23+
Quick sort;
24+
25+
// ACT
26+
SortSequence sequence = TestSort::GenerateSequence(&sort);
27+
28+
// ASSERT
29+
const std::vector<Rect::Rectangle>& lastStep = *(sequence.steps->at(sequence.stepCount - 1).rects);
30+
for (int i = 0; i < TestSort::LIST_SIZE; ++i) {
31+
EXPECT_EQ(lastStep[i].value, i + 1);
32+
EXPECT_EQ(lastStep[i].state, Rect::State::ORDERED);
33+
}
34+
}

0 commit comments

Comments
 (0)