Skip to content

Commit 11c5fde

Browse files
Merge branch 'master' into cstdint
2 parents f063687 + ef209df commit 11c5fde

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

sorting/quick_sort_iterative.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
/**
21+
* @namespace sorting
22+
* @brief Sorting algorithms
23+
*/
24+
namespace sorting {
25+
/**
26+
* @brief The partition function sorts the array from
27+
* start to end and uses the last element as the pivot.
28+
* @param arr the array to be sorted
29+
* @param start starting index
30+
* @param end ending index
31+
* @return int next index of the pivot
32+
*/
33+
int partition(std::vector<int> &arr, int start, int end)
34+
{
35+
int pivot = arr[end];
36+
int index = start - 1;
37+
38+
for (int j = start; j < end; j++) {
39+
if (arr[j] <= pivot) {
40+
std::swap(arr[++index], arr[j]);
41+
}
42+
}
43+
44+
std::swap(arr[index + 1], arr[end]);
45+
return index + 1;
46+
}
47+
48+
/**
49+
* @brief The main sorting function
50+
* @details The iterative quick sort uses
51+
* the stack instead of recursion for saving
52+
* and restoring the environment between calls.
53+
* It does not need the end and start params, because
54+
* it is not recursive.
55+
* @param arr array to be sorted
56+
* @return void
57+
*/
58+
void iterativeQuickSort(std::vector<int> &arr)
59+
{
60+
std::stack<int> stack;
61+
int start = 0;
62+
int end = arr.size()-1;
63+
stack.push(start);
64+
stack.push(end);
65+
66+
while(!stack.empty())
67+
{
68+
end = stack.top();
69+
stack.pop();
70+
start = stack.top();
71+
stack.pop();
72+
73+
int pivotIndex = partition(arr,start,end);
74+
75+
if(pivotIndex -1 > start)
76+
{
77+
stack.push(start);
78+
stack.push(pivotIndex-1);
79+
}
80+
81+
if(pivotIndex+1<end)
82+
{
83+
stack.push(pivotIndex+1);
84+
stack.push(end);
85+
}
86+
}
87+
}
88+
89+
} // namespace sorting
90+
/**
91+
* @brief Self-test implementations
92+
* @returns void
93+
*/
94+
void tests()
95+
{
96+
//TEST 1 - Positive numbers
97+
std::vector<int> case1={100,534,1000000,553,10,61,2000,238,2756,9,12,56,30};
98+
std::cout<<"TEST 1\n";
99+
std::cout<<"Before: \n";
100+
for(auto x : case1) std::cout<<x<<",";
101+
std::cout<<"\n";
102+
sorting::iterativeQuickSort(case1);
103+
assert(std::is_sorted(std::begin(case1),std::end(case1)));
104+
std::cout<<"Test 1 succesful!\n";
105+
std::cout<<"After: \n";
106+
for(auto x : case1) std::cout<<x<<",";
107+
std::cout<<"\n";
108+
109+
//TEST 2 - Negative numbers
110+
std::vector<int> case2={-10,-2,-5,-2,-3746,-785,-123, -452, -32456};
111+
std::cout<<"TEST 2\n";
112+
std::cout<<"Before: \n";
113+
for(auto x : case2) std::cout<<x<<",";
114+
std::cout<<"\n";
115+
sorting::iterativeQuickSort(case2);
116+
assert(std::is_sorted(std::begin(case2),std::end(case2)));
117+
std::cout<<"Test 2 succesful!\n";
118+
std::cout<<"After: \n";
119+
for(auto x : case2) std::cout<<x<<",";
120+
std::cout<<"\n";
121+
}
122+
123+
124+
/**
125+
* @brief Main function
126+
* @returns 0 on exit
127+
*/
128+
int main()
129+
{
130+
tests(); // run self test implementation
131+
return 0;
132+
}

0 commit comments

Comments
 (0)