Skip to content

Commit 08c4a3f

Browse files
kvedalasinkyoungdeokgithub-actions
authored
feat: Added merge-insertion sort from TheAlgorithms#246 (TheAlgorithms#1062)
* Create Merge-insertion sort.cpp * fixed file path * working code * added documentation * replace c-style array with std::array * updating DIRECTORY.md * clang-format and clang-tidy fixes for 8b3a663 Co-authored-by: sinkyoungdeok <tlsrudejr123@nate.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
1 parent a9da541 commit 08c4a3f

File tree

3 files changed

+174
-6
lines changed

3 files changed

+174
-6
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@
236236
* [Heap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/heap_sort.cpp)
237237
* [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/insertion_sort.cpp)
238238
* [Library Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/library_sort.cpp)
239+
* [Merge Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/merge_insertion_sort.cpp)
239240
* [Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/merge_sort.cpp)
240241
* [Non Recursive Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/non_recursive_merge_sort.cpp)
241242
* [Numeric String Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/numeric_string_sort.cpp)

data_structures/skip_list.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class SkipList {
6464
SkipList() {
6565
level = 0;
6666
// Header initialization
67-
header = std::shared_ptr<Node>(new Node(-1, MAX_LEVEL));
67+
header = std::make_shared<Node>(-1, MAX_LEVEL);
6868
}
6969

7070
/**
@@ -75,8 +75,9 @@ class SkipList {
7575
int randomLevel() {
7676
int lvl = 0;
7777
while (static_cast<float>(std::rand()) / RAND_MAX < PROBABILITY &&
78-
lvl < MAX_LEVEL)
78+
lvl < MAX_LEVEL) {
7979
lvl++;
80+
}
8081
return lvl;
8182
}
8283

@@ -93,8 +94,9 @@ class SkipList {
9394
update.fill(nullptr);
9495

9596
for (int i = level; i >= 0; i--) {
96-
while (x->forward[i] != nullptr && x->forward[i]->key < key)
97+
while (x->forward[i] != nullptr && x->forward[i]->key < key) {
9798
x = x->forward[i];
99+
}
98100
update[i] = x;
99101
}
100102

@@ -112,7 +114,7 @@ class SkipList {
112114
}
113115

114116
std::shared_ptr<Node> n =
115-
std::shared_ptr<Node>(new Node(key, rlevel, value));
117+
std::make_shared<Node>(key, rlevel, value);
116118
for (int i = 0; i <= rlevel; i++) {
117119
n->forward[i] = update[i]->forward[i];
118120
update[i]->forward[i] = n;
@@ -135,8 +137,9 @@ class SkipList {
135137
update.fill(nullptr);
136138

137139
for (int i = level; i >= 0; i--) {
138-
while (x->forward[i] != nullptr && x->forward[i]->key < key)
140+
while (x->forward[i] != nullptr && x->forward[i]->key < key) {
139141
x = x->forward[i];
142+
}
140143
update[i] = x;
141144
}
142145

@@ -146,8 +149,9 @@ class SkipList {
146149

147150
if (!doesnt_exist) {
148151
for (int i = 0; i <= level; i++) {
149-
if (update[i]->forward[i] != x)
152+
if (update[i]->forward[i] != x) {
150153
break;
154+
}
151155
update[i]->forward[i] = x->forward[i];
152156
}
153157
/* Remove empty levels*/

sorting/merge_insertion_sort.cpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* @file
3+
* @author [@sinkyoungdeok](https://github.com/sinkyoungdeok)
4+
* @author [Krishna Vedala](https://github.com/kvedala)
5+
* @brief Algorithm that combines insertion sort and merge sort. [Wiki
6+
* link](https://en.wikipedia.org/wiki/Merge-insertion_sort)
7+
*
8+
* @see Individual algorithms: insertion_sort.cpp and merge_sort.cpp
9+
*/
10+
#include <algorithm>
11+
#include <array>
12+
#include <cassert>
13+
#include <ctime>
14+
#include <iostream>
15+
#include <memory>
16+
17+
/** \namespace sorting
18+
* \brief Sorting algorithms
19+
*/
20+
namespace sorting {
21+
/** \namespace merge_insertion
22+
* \brief Combined Intersion-Merge sorting algorithm
23+
*/
24+
namespace merge_insertion {
25+
26+
/**
27+
* @brief Insertion merge algorithm
28+
* @see insertion_sort.cpp
29+
*
30+
* @tparam T array data type
31+
* @tparam N length of array
32+
* @param A pointer to array to sort
33+
* @param start start index of sorting window
34+
* @param end end index of sorting window
35+
*/
36+
template <typename T, size_t N>
37+
static void InsertionSort(std::array<T, N> *A, size_t start, size_t end) {
38+
size_t i = 0, j = 0;
39+
T *ptr = A->data();
40+
41+
for (i = start; i < end; i++) {
42+
T temp = ptr[i];
43+
j = i;
44+
while (j > start && temp < ptr[j - 1]) {
45+
ptr[j] = ptr[j - 1];
46+
j--;
47+
}
48+
// for (j = i; j > start && temp < ptr[j - 1]; --j) {
49+
// ptr[j] = ptr[j - 1];
50+
// }
51+
52+
ptr[j] = temp;
53+
}
54+
}
55+
56+
/**
57+
* @brief Perform merge of data in a window
58+
*
59+
* @tparam T array data type
60+
* @tparam N length of array
61+
* @param A pointer to array to sort
62+
* @param min start index of window
63+
* @param max end index of window
64+
* @param mid mid-point of window
65+
*/
66+
template <typename T, size_t N>
67+
static void merge(std::array<T, N> *array, size_t min, size_t max, size_t mid) {
68+
size_t firstIndex = min;
69+
size_t secondIndex = mid + 1;
70+
71+
auto ptr = array->data();
72+
std::array<T, N + 1> tempArray{0};
73+
74+
// While there are elements in the left or right runs
75+
for (size_t index = min; index <= max; index++) {
76+
// If left run head exists and is <= existing right run head.
77+
if (firstIndex <= mid &&
78+
(secondIndex > max || ptr[firstIndex] <= ptr[secondIndex])) {
79+
tempArray[index] = ptr[firstIndex];
80+
firstIndex++;
81+
} else {
82+
tempArray[index] = ptr[secondIndex];
83+
secondIndex++;
84+
}
85+
}
86+
87+
// transfer to the initial array
88+
memcpy(ptr + min, tempArray.data() + min, (max - min) * sizeof(T));
89+
// for (int index = min; index <= max; index++) ptr[index] =
90+
// tempArray[index];
91+
}
92+
93+
/**
94+
* @brief Final combined algorithm.
95+
* Algorithm utilizes ::sorting::merge_insertion::InsertionSort if window length
96+
* is less than threshold, else performs merge sort recursively using
97+
* ::sorting::merge_insertion::mergeSort
98+
*
99+
* @tparam T array data type
100+
* @tparam N length of array
101+
* @param A pointer to array to sort
102+
* @param min start index of sort window
103+
* @param max end index of sort window
104+
* @param threshold window length threshold
105+
*/
106+
template <typename T, size_t N>
107+
void mergeSort(std::array<T, N> *array, size_t min, size_t max,
108+
size_t threshold) {
109+
// prerequisite
110+
if ((max - min) <= threshold) {
111+
InsertionSort(array, min, max);
112+
} else {
113+
// get the middle point
114+
size_t mid = (max + min) >> 1;
115+
116+
// apply merge sort to both parts of this
117+
mergeSort(array, min, mid, threshold);
118+
mergeSort(array, mid, max, threshold);
119+
120+
// and finally merge all that sorted stuff
121+
merge(array, min, max, mid);
122+
}
123+
}
124+
125+
} // namespace merge_insertion
126+
} // namespace sorting
127+
128+
/**
129+
* @brief Function to test code using random arrays
130+
* @returns none
131+
*/
132+
static void test() {
133+
constexpr size_t size = 30;
134+
std::array<int, size> array{0};
135+
// input
136+
for (int i = 0; i < size; i++) {
137+
array[i] = std::rand() % 100 - 50;
138+
std::cout << array[i] << " ";
139+
}
140+
std::cout << std::endl;
141+
142+
sorting::merge_insertion::InsertionSort(&array, 0, size);
143+
// sorting::merge_insertion::mergeSort(&array, 0, size, 10);
144+
145+
// output
146+
for (int i = 0; i < size; ++i) {
147+
std::cout << array[i] << " ";
148+
}
149+
std::cout << std::endl;
150+
151+
assert(std::is_sorted(std::begin(array), std::end(array)));
152+
std::cout << "Test passed\n";
153+
}
154+
155+
/**
156+
* @brief Main function
157+
* @return 0 on exit
158+
*/
159+
int main() {
160+
std::srand(std::time(nullptr));
161+
test();
162+
return 0;
163+
}

0 commit comments

Comments
 (0)