Skip to content

Commit 93f5432

Browse files
committed
feat: Added iterative quick sort using stack
1 parent 2dadbf7 commit 93f5432

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

sorting/quick_sort_iterative.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* @file
3+
* @brief Quick Sort without recursion. This method uses the stack instead.
4+
* Both recursive and iterative implementations have O(n log n) best case
5+
* and O(n^2) worst case.
6+
* @details
7+
* https://stackoverflow.com/questions/12553238/quicksort-iterative-or-recursive
8+
* https://en.wikipedia.org/wiki/Quicksort
9+
* https://www.geeksforgeeks.org/iterative-quick-sort/
10+
* @author Sebe324 (https://github.com/sebe324)
11+
*/
12+
13+
#include <iostream> //for std::cout
14+
#include <vector> //for std::vector
15+
#include <stack> //for std::stack
16+
#include <algorithm> //for std::is_sorted
17+
#include <cassert> //for assert
18+
19+
/**
20+
* @brief The partition function sorts the array from
21+
* start to end and uses the last element as the pivot.
22+
* @param arr the array to be sorted
23+
* @param start starting index
24+
* @param end ending index
25+
* @return int next index of the pivot
26+
*/
27+
int partition(std::vector<int> &arr, int start, int end)
28+
{
29+
int pivot = arr[end];
30+
int index = start - 1;
31+
32+
for (int j = start; j < end; j++) {
33+
if (arr[j] <= pivot) {
34+
std::swap(arr[++index], arr[j]);
35+
}
36+
}
37+
38+
std::swap(arr[index + 1], arr[end]);
39+
return index + 1;
40+
}
41+
42+
/**
43+
* @brief The main sorting function
44+
* @details The iterative quick sort uses
45+
* the stack instead of recursion for saving
46+
* and restoring the environment between calls.
47+
* It does not need the end and start params, because
48+
* it is not recursive.
49+
* @return void
50+
*/
51+
void iterativeQuickSort(std::vector<int> &arr)
52+
{
53+
std::stack<int> stack;
54+
int start = 0;
55+
int end = arr.size()-1;
56+
stack.push(start);
57+
stack.push(end);
58+
59+
while(!stack.empty())
60+
{
61+
end = stack.top();
62+
stack.pop();
63+
start = stack.top();
64+
stack.pop();
65+
66+
int pivotIndex = partition(arr,start,end);
67+
68+
if(pivotIndex -1 > start)
69+
{
70+
stack.push(start);
71+
stack.push(pivotIndex-1);
72+
}
73+
74+
if(pivotIndex+1<end)
75+
{
76+
stack.push(pivotIndex+1);
77+
stack.push(end);
78+
}
79+
}
80+
}
81+
82+
/**
83+
* @brief Self-test implementations
84+
* @returns void
85+
*/
86+
void tests()
87+
{
88+
//TEST 1 - Positive numbers
89+
std::vector<int> case1={100,534,1000000,553,10,61,2000,238,2756,9,12,56,30};
90+
std::cout<<"TEST 1\n";
91+
std::cout<<"Before: \n";
92+
for(auto x : case1) std::cout<<x<<",";
93+
std::cout<<"\n";
94+
iterativeQuickSort(case1);
95+
assert(std::is_sorted(std::begin(case1),std::end(case1)));
96+
std::cout<<"Test 1 succesful!\n";
97+
std::cout<<"After: \n";
98+
for(auto x : case1) std::cout<<x<<",";
99+
std::cout<<"\n";
100+
101+
//TEST 2 - Negative numbers
102+
std::vector<int> case2={-10,-2,-5,-2,-3746,-785,-123, -452, -32456};
103+
std::cout<<"TEST 2\n";
104+
std::cout<<"Before: \n";
105+
for(auto x : case2) std::cout<<x<<",";
106+
std::cout<<"\n";
107+
iterativeQuickSort(case2);
108+
assert(std::is_sorted(std::begin(case2),std::end(case2)));
109+
std::cout<<"Test 2 succesful!\n";
110+
std::cout<<"After: \n";
111+
for(auto x : case2) std::cout<<x<<",";
112+
std::cout<<"\n";
113+
}
114+
115+
116+
/**
117+
* @brief Main function
118+
* @returns 0 on exit
119+
*/
120+
int main()
121+
{
122+
tests();
123+
return 0;
124+
}

0 commit comments

Comments
 (0)