TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
quick_sort_3.cpp
Go to the documentation of this file.
1
12#include <algorithm>
13#include <cassert>
14#include <ctime>
15#include <iostream>
16#include <vector>
17
18namespace {
24template <typename T>
25std::ostream &operator<<(std::ostream &out, const std::vector<T> &arr) {
26 for (size_t i = 0; i < arr.size(); ++i) {
27 out << arr[i];
28 if (i < arr.size() - 1) {
29 out << ", ";
30 }
31 }
32 return out;
33}
34
35} // namespace
36
41namespace sorting {
42namespace { // using un-named namespace here to prevent partition function
43 // being visible to end-users
55template <typename T>
56void partition3(std::vector<T> *arr, int32_t low, int32_t high, int32_t *i,
57 int32_t *j) {
58 // To handle 2 elements
59 if (high - low <= 1) {
60 if ((*arr)[high] < (*arr)[low]) {
61 std::swap((*arr)[high], (*arr)[low]);
62 }
63 *i = low;
64 *j = high;
65 return;
66 }
67
68 int32_t mid = low;
69 T pivot = (*arr)[high];
70 while (mid <= high) {
71 if ((*arr)[mid] < pivot) {
72 std::swap((*arr)[low++], (*arr)[mid++]);
73 } else if ((*arr)[mid] == pivot) {
74 mid++;
75 } else if ((*arr)[mid] > pivot) {
76 std::swap((*arr)[mid], (*arr)[high--]);
77 }
78 }
79
80 // update i and j
81 *i = low - 1;
82 *j = mid; // or high-1
83}
84} // namespace
85
93template <typename T>
94void quicksort(std::vector<T> *arr, int32_t low, int32_t high) {
95 if (low >= high) { // 1 or 0 elements
96 return;
97 }
98
99 int32_t i = 0, j = 0;
100
101 // i and j are passed as reference
102 partition3(arr, low, high, &i, &j);
103
104 // Recur two halves
105 quicksort(arr, low, i);
106 quicksort(arr, j, high);
107}
108
118template <typename T>
119std::vector<T> quicksort(std::vector<T> arr, int32_t low, int32_t high) {
120 if (low >= high) { // 1 or 0 elements
121 return arr;
122 }
123
124 int32_t i = 0, j = 0;
125
126 // i and j are passed as reference
127 partition3(&arr, low, high, &i, &j);
128
129 // Recur two halves
130 quicksort(&arr, low, i);
131 quicksort(&arr, j, high);
132
133 return arr;
134}
135} // namespace sorting
136
138static void test_int() {
139 std::cout << "\nTesting integer type arrays\n";
140
141 for (int num_tests = 1; num_tests < 21; num_tests++) {
142 size_t size = std::rand() % 500;
143 std::vector<int> arr(size);
144 for (auto &a : arr) {
145 a = std::rand() % 500 - 250; // random numbers between -250, 249
146 }
147
148 std::cout << "Test " << num_tests << "\t Array size:" << size << "\t ";
149 std::vector<int> sorted = sorting::quicksort(arr, 0, int32_t(size) - 1);
150 if (size < 20) {
151 std::cout << "\t Sorted Array is:\n\t";
152 std::cout << sorted << "\n";
153 }
154 assert(std::is_sorted(std::begin(sorted), std::end(sorted)));
155 std::cout << "\t Passed\n";
156 }
157}
158
160static void test_double() {
161 std::cout << "\nTesting Double type arrays\n";
162 for (int num_tests = 1; num_tests < 21; num_tests++) {
163 size_t size = std::rand() % 500;
164 std::vector<double> arr(size);
165 for (auto &a : arr) {
166 a = double(std::rand() % 500) -
167 250.f; // random numbers between -250, 249
168 a /= 100.f; // convert to -2.5 to 2.49
169 }
170
171 std::cout << "Test " << num_tests << "\t Array size:" << size << "\t ";
172 std::vector<double> sorted =
173 sorting::quicksort(arr, 0, int32_t(size) - 1);
174 if (size < 20) {
175 std::cout << "\t Sorted Array is:\n\t";
176 std::cout << sorted << "\n";
177 }
178 assert(std::is_sorted(std::begin(sorted), std::end(sorted)));
179 std::cout << "\t Passed\n";
180 }
181}
182
184int main() {
185 std::srand(std::time(nullptr));
186 test_int();
187 test_double();
188 return 0;
189}
static std::ostream & operator<<(std::ostream &out, matrix< T > const &v)
for working with vectors
void quicksort(std::vector< T > *arr, int32_t low, int32_t high)
static void test_int()
static void test_double()
int main()