Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/sort.hpp
2 views
1
#ifndef NALL_SORT_HPP
2
#define NALL_SORT_HPP
3
4
#include <algorithm>
5
#include <nall/utility.hpp>
6
7
//class: merge sort
8
//average: O(n log n)
9
//worst: O(n log n)
10
//memory: O(n)
11
//stack: O(log n)
12
//stable?: yes
13
14
//note: merge sort was chosen over quick sort, because:
15
//* it is a stable sort
16
//* it lacks O(n^2) worst-case overhead
17
18
#define NALL_SORT_INSERTION
19
//#define NALL_SORT_SELECTION
20
21
namespace nall {
22
template<typename T, typename Comparator>
23
void sort(T list[], unsigned size, const Comparator &lessthan) {
24
if(size <= 1) return; //nothing to sort
25
26
//use insertion sort to quickly sort smaller blocks
27
if(size < 64) {
28
#if defined(NALL_SORT_INSERTION)
29
for(signed i = 1, j; i < size; i++) {
30
T copy = std::move(list[i]);
31
for(j = i - 1; j >= 0; j--) {
32
if(lessthan(list[j], copy)) break;
33
list[j + 1] = std::move(list[j]);
34
}
35
list[j + 1] = std::move(copy);
36
}
37
#elif defined(NALL_SORT_SELECTION)
38
for(unsigned i = 0; i < size; i++) {
39
unsigned min = i;
40
for(unsigned j = i + 1; j < size; j++) {
41
if(lessthan(list[j], list[min])) min = j;
42
}
43
if(min != i) std::swap(list[i], list[min]);
44
}
45
#endif
46
return;
47
}
48
49
//split list in half and recursively sort both
50
unsigned middle = size / 2;
51
sort(list, middle, lessthan);
52
sort(list + middle, size - middle, lessthan);
53
54
//left and right are sorted here; perform merge sort
55
T *buffer = new T[size];
56
unsigned offset = 0, left = 0, right = middle;
57
while(left < middle && right < size) {
58
if(lessthan(list[left], list[right])) {
59
buffer[offset++] = std::move(list[left++]);
60
} else {
61
buffer[offset++] = std::move(list[right++]);
62
}
63
}
64
while(left < middle) buffer[offset++] = std::move(list[left++]);
65
while(right < size) buffer[offset++] = std::move(list[right++]);
66
67
for(unsigned i = 0; i < size; i++) list[i] = std::move(buffer[i]);
68
delete[] buffer;
69
}
70
71
template<typename T>
72
void sort(T list[], unsigned size) {
73
return sort(list, size, [](const T &l, const T &r) { return l < r; });
74
}
75
}
76
77
#endif
78
79