-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsorting.cpp
146 lines (130 loc) · 3.69 KB
/
sorting.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
#include <iostream>
#include <chrono> // for timing
#include <concepts> // for std::integral concept
#include <string_view> // for std::string_view
#include <ctime> // for std::time()
#include <cstdlib> // for std::srand() and std::rand()
// The name of the array is not important here, so we just use ampersand only
template<std::integral auto N>
static auto constexpr array_length(auto (&)[N]) noexcept -> decltype(N)
{
return N;
}
template<template<typename> typename S, typename T, auto N>
concept Sorter = requires(S<T>& sorter, T (&array)[N])
{
sorter(array);
};
// NOTE: There is a difference between class template typenames and just normal typenames
// Class template typenames (with one template parameter) are declared as: template<typename> typename
// While the normal typename is declared as just: typename
template<template<typename> typename TSorter, typename T, std::integral auto N> requires(Sorter<TSorter, T, N>)
static constexpr void sort(T (&array)[N]) noexcept
{
return TSorter<T> { } (array);
}
template<typename T, std::integral auto N>
static constexpr void scramble(T (&array)[N]) noexcept
{
using SizeType = decltype(N);
for(SizeType i = 0; i < N; ++i)
std::swap(array[i], array[std::rand() % N]);
}
template<typename T, std::integral auto N>
static constexpr void print_array(const std::string_view desc, T (&array)[N]) noexcept
{
std::cout << desc << ": ";
using SizeType = decltype(N);
for(SizeType i = 0; i < N; ++i)
std::cout << array[i] << " ";
std::cout << std::endl;
}
// Bubble sort strategy
template<typename S>
struct bubble_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
// Merge sort strategy
template<typename S>
struct merge_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
// Quick sort strategy
template<typename S>
struct quick_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
// Heap sort strategy
template<typename S>
struct heap_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
// Insertion sort strategy
template<typename S>
struct insertion_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
// Selection sort strategy
template<typename S>
struct selection_sort
{
template<typename T = S, std::integral auto N>
void operator() (T (&array)[N]) noexcept
{
(void)array;
}
};
static constexpr auto get_elapsed(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) noexcept
{
return std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(end - start).count();
}
template<template<typename> typename Sorter, typename T, std::integral auto N>
static void run(const std::string_view desc, T (&array)[N]) noexcept
{
scramble(array);
print_array("Input", array);
auto start = std::chrono::steady_clock::now();
sort<Sorter>(array);
auto end = std::chrono::steady_clock::now();
std::cout << desc << ": " << get_elapsed(start, end) << " ms" << std::endl;
print_array("Output", array);
}
int main()
{
std::srand(std::time(nullptr));
int array[] = { 23, 3, 43, 1, 2, 4, 6, -4, 6, -100, -200, -4, -6, 0, 1, 0, 2, 0, 23, -100, -333 };
auto length = array_length(array);
std::cout << "Input Size: " << length << std::endl;
run<bubble_sort>("Bubble Sort", array);
run<merge_sort>("Merge Sort", array);
run<insertion_sort>("Insertion Sort", array);
run<selection_sort>("Selection Sort", array);
run<heap_sort>("Heap Sort", array);
run<quick_sort>("Quick Sort", array);
return 0;
}