-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqsort1block.h
98 lines (80 loc) · 2.87 KB
/
qsort1block.h
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
/******************************************************************************
* src/algorithms/qsort1is.h
*
* Sorting using Quicksort, single pivot, version 2, with base case networks
*
******************************************************************************
* Copyright (C) 2014 Martin Aumüller <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <algorithm>
#include <iostream>
namespace qsort1lomutoblock {
#define BLOCKSIZE 512
template <typename Iterator>
void sort(Iterator lo, Iterator hi)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::difference_type index;
index block[BLOCKSIZE];
Iterator pivot_position;
if (lo + 16 >= hi) {
return InsertionSort(lo, hi - lo + 1);
}
else if (lo + 100 < hi) {
pivot_position = pivot_strategies::median_of_5_medians_of_5(lo, hi);
}
else {
pivot_position = pivot_strategies::median_of_3(lo, hi);
}
std::iter_swap(pivot_position, hi);
pivot_position = hi;
const value_type pivot = *hi;
Iterator counter = lo, offset = lo;
int num_left = 0;
while (hi - counter > BLOCKSIZE) {
for (index j = 0; j < BLOCKSIZE; ++j) {
block[num_left] = j;
num_left += (pivot > counter[j]);
}
for (index j = 0; j < num_left; j++) {
std::iter_swap(offset, counter + block[j]);
offset++;
}
num_left = 0;
counter += BLOCKSIZE;
}
for (index j = 0; j < hi - counter; ++j) {
block[num_left] = j;
num_left += (pivot > counter[j]);
}
for (index j = 0; j < num_left; j++) {
std::iter_swap(offset, counter + block[j]);
offset++;
}
std::iter_swap(offset, pivot_position);
sort(lo, offset - 1);
sort(offset + 1, hi);
}
template <typename ValueType>
void qsort1()
{
assert( g_input_size % sizeof(ValueType) == 0 );
ValueType* input = (ValueType*)g_input;
size_t n = g_input_size / sizeof(ValueType);
sort(input, input + n - 1);
}
CONTESTANT_REGISTER_ALL(qsort1, "qsort1lomutoblock", "Quicksort, single pivot, lomuto, block")
} // namespace qsort1is