-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
/
gnome_sort.cpp
133 lines (122 loc) · 3.99 KB
/
gnome_sort.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* @file
* @brief Implementation of [gnome
* sort](https://en.wikipedia.org/wiki/Gnome_sort) algorithm.
* @author [beqakd](https://github.com/beqakd)
* @author [Krishna Vedala](https://github.com/kvedala)
* @details
* Gnome sort algorithm is not the best one but it is widely used.
* The algorithm iteratively checks the order of pairs in the array. If they are
* on right order it moves to the next successive pair, otherwise it swaps
* elements. This operation is repeated until no more swaps are made thus
* indicating the values to be in ascending order.
*
* The time Complexity of the algorithm is \f$O(n^2)\f$ and in some cases it
* can be \f$O(n)\f$.
*/
#include <algorithm> // for std::swap
#include <array> // for std::array
#include <cassert> // for assertions
#include <iostream> // for io operations
/**
* @namespace sorting
* Sorting algorithms
*/
namespace sorting {
/**
* This implementation is for a C-style array input that gets modified in place.
* @param [in,out] arr our array of elements.
* @param size size of given array
*/
template <typename T>
void gnomeSort(T *arr, int size) {
// few easy cases
if (size <= 1) {
return;
}
int index = 0; // initialize some variables.
while (index < size) {
// check for swap
if ((index == 0) || (arr[index] >= arr[index - 1])) {
index++;
} else {
std::swap(arr[index], arr[index - 1]); // swap
index--;
}
}
}
/**
* This implementation is for a C++-style array input. The function argument is
* a pass-by-value and hence a copy of the array gets created which is then
* modified by the function and returned.
* @tparam T type of data variables in the array
* @tparam size size of the array
* @param [in] arr our array of elements.
* @return array with elements sorted
*/
template <typename T, size_t size>
std::array<T, size> gnomeSort(std::array<T, size> arr) {
// few easy cases
if (size <= 1) {
return arr;
}
int index = 0; // initialize loop index
while (index < size) {
// check for swap
if ((index == 0) || (arr[index] >= arr[index - 1])) {
index++;
} else {
std::swap(arr[index], arr[index - 1]); // swap
index--;
}
}
return arr;
}
} // namespace sorting
/**
* Test function
*/
static void test() {
// Example 1. Creating array of int,
std::cout << "Test 1 - as a C-array...";
const int size = 6;
std::array<int, size> arr = {-22, 100, 150, 35, -10, 99};
sorting::gnomeSort(arr.data(),
size); // pass array data as a C-style array pointer
assert(std::is_sorted(std::begin(arr), std::end(arr)));
std::cout << " Passed\n";
for (int i = 0; i < size; i++) {
std::cout << arr[i] << ", ";
}
std::cout << std::endl;
// Example 2. Creating array of doubles.
std::cout << "\nTest 2 - as a std::array...";
std::array<double, size> double_arr = {-100.2, 10.2, 20.0, 9.0, 7.5, 7.2};
std::array<double, size> sorted_arr = sorting::gnomeSort(double_arr);
assert(std::is_sorted(std::begin(sorted_arr), std::end(sorted_arr)));
std::cout << " Passed\n";
for (int i = 0; i < size; i++) {
std::cout << double_arr[i] << ", ";
}
std::cout << std::endl;
// Example 3. Creating random array of float.
std::cout << "\nTest 3 - 200 random numbers as a std::array...";
const int size2 = 200;
std::array<float, size2> rand_arr{};
for (auto &a : rand_arr) {
// generate random numbers between -5.0 and 4.99
a = float(std::rand() % 1000 - 500) / 100.f;
}
std::array<float, size2> float_arr = sorting::gnomeSort(rand_arr);
assert(std::is_sorted(std::begin(float_arr), std::end(float_arr)));
std::cout << " Passed\n";
// for (int i = 0; i < size; i++) std::cout << double_arr[i] << ", ";
std::cout << std::endl;
}
/**
* Our main function with example of sort method.
*/
int main() {
test();
return 0;
}