-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsorting_algorithms_in_Rcpp.cpp
171 lines (159 loc) · 5.24 KB
/
sorting_algorithms_in_Rcpp.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include < Rcpp.h >
using namespace Rcpp;
// function to interchange elements of an array at two positions
void swap(NumericVector array, int first_position, int second_position) {
double temporary = array[first_position];
array[first_position] = array[second_position];
array[second_position] = temporary;
}
// function to calculate median of the first, last middlemost elements of an array
int median_of_three(NumericVector array, int start, int end) {
int middle = (start + end) / 2;
if (array[start] > array[end]) {
swap(array, start, end);
}
if (array[middle] > array[end]) {
swap(array, middle, end);
}
if (array[start] > array[middle]) {
swap(array, start, middle);
}
return middle;
}
// partition algorithm for quick sort using first element as pivot
int partition_hoare(NumericVector array, int start, int end) {
double pivot = array[start];
int i = (start - 1);
int j = (end + 1);
while (TRUE) {
do {
i = (i + 1);
} while (array[i] < pivot);
do {
j = (j - 1);
} while (array[j] > pivot);
if (i >= j) {
return j;
}
swap(array, i, j);
}
}
// partition algorithm for quick sort using last element as pivot
int partition_lomuto(NumericVector array, int start, int end) {
double pivot = array[end];
int i = (start - 1);
for (int j = start; j < end; ++j) {
if (array[j] <= pivot) {
i = (i + 1);
swap(array, i, j);
}
}
swap(array, (i + 1), end);
return (i + 1);
}
// partition algorithm for quick sort using random element as pivot
int partition_lomuto_random(NumericVector array, int start, int end) {
int key = rand() % (end - start + 1) + start;
swap(array, key, end);
return partition_lomuto(array, start, end);
}
// partition algorithm for quick sort using median of first, last and middlemost elements as pivot
int partition_hoare_singleton(NumericVector array, int start, int end) {
int key = median_of_three(array, start, end);
swap(array, start, key);
return partition_hoare(array, start, end);
}
// insertion sort algorithm
void insertion(NumericVector array, int start, int end) {
if (start < end) {
for (int i = (start + 1); i <= end; ++i) {
double temporary = array[i];
int j = (i - 1);
while ((j >= start) && (array[j] > temporary)) {
array[(j + 1)] = array[j];
j = (j - 1);
}
array[(j + 1)] = temporary;
}
}
}
// quick sort algorithm using first element as pivot
void quick_hoare(NumericVector array, int start, int end) {
if (start < end) {
int key = partition_hoare(array, start, end);
quick_hoare(array, start, key);
quick_hoare(array, (key + 1), end);
}
}
// quick sort algorithm using median of three pivot
void quick_hoare_singleton(NumericVector array, int start, int end) {
if (start < end) {
int key = partition_hoare_singleton(array, start, end);
quick_hoare_singleton(array, start, key);
quick_hoare_singleton(array, (key + 1), end);
}
}
// hybrid sort algorithm using first element as pivot
void hybrid_hoare(NumericVector array, int start, int end, int cutoff) {
if (start < end) {
// applying partition algorithm only when array size is more than cutoff
if ((end - start + 1) > cutoff) {
int key = partition_hoare(array, start, end);
hybrid_hoare(array, start, key, cutoff);
hybrid_hoare(array, (key + 1), end, cutoff);
}
}
}
// hybrid sort algorithm using random element as pivot
void hybrid_lomuto_random(NumericVector array, int start, int end, int cutoff) {
if (start < end) {
// applying partition algorithm only when array size is more than cutoff
if ((end - start + 1) > cutoff) {
int key = partition_lomuto_random(array, start, end);
hybrid_lomuto_random(array, start, key, cutoff);
hybrid_lomuto_random(array, (key + 1), end, cutoff);
}
}
}
// [[Rcpp::export]]
// function to be called from R to use the sorting algorithms defined above
NumericVector sorting_R(NumericVector array, int method = 1, int cutoff) {
int n = array.length();
// making an explicit copy of the input array to keep that unchanged
NumericVector sorted_array = clone(array);
// applying different sorting algorithms based on user input on method
switch (method) {
case 1:
{
hybrid_hoare(sorted_array, 0, (n - 1), cutoff);
insertion(sorted_array, 0, (n - 1));
break;
}
case 2:
{
hybrid_lomuto_random(sorted_array, 0, (n - 1), cutoff);
insertion(sorted_array, 0, (n - 1));
break;
}
case 3:
{
insertion(sorted_array, 0, (n - 1));
break;
}
case 4:
{
quick_hoare(sorted_array, 0, (n - 1));
break;
}
case 5:
{
quick_hoare_singleton(sorted_array, 0, (n - 1));
break;
}
default:
{
Rcpp::stop("Permissible values are 1 to 5", FALSE);
}
}
return sorted_array;
}