1 #include <iostream>
2 #include <vector>
3
4 std::vector<int> g_array {
5 12, 3, 52, 65, 9, 29,16, 7, 2, 78, 63, 98, 23, 43, 1, 24, 84, 34, 94, 32
6 };
7 void Swap(std::vector<int>& array, int i, int j) {
8 int temp = array[j];
9 array[j] = array[i];
10 array[i] = temp;
11 }
12 void ShowArray(std::vector<int>& array) {
13 for (int i = 0; i < array.size(); ++i) {
14 std::cout << array[i] << " ";
15 }
16 std::cout << "\n";
17 }
18
19 // ----------------比较排序-----------------
20 // 冒泡排序:交换,时间复杂度O(n)- O(n2),空间复杂度O(1)
21 void BubbleSort(std::vector<int>& array);
22 // 快速排序:分治法+交换+双重游标,时间复杂度O(nlogn) - O(n2),空间复杂度O(nlogn).递归算法每次都要存储栈信息,因此为nlogn
23 void QuickSort(std::vector<int>& array, int begin, int end);
24 // 插入排序:有序子序列 + 插入位置 + 连续数量移动,时间复杂度O(n) - O(n2),空间复杂度O(1)
25 void InsertionSort1(std::vector<int>& array); // 找到位置后移动
26 void InsertionSort2(std::vector<int>& array); // 比较相邻元素,然后交互
27 // shell 排序:宏观调控 + 增量子序列 + 增量减少至1。时间复杂度O(n1.3) - O(n2),空间复杂度O(1)。shell增量的选择是个数学难题,一般采用length/作为步长
28 void ShellSort1(std::vector<int>& array); // 找到位置后移动
29 void ShellSort2(std::vector<int>& array); // 比较相邻元素,然后交互
30 // 选择排序.O(n2),空间复杂度O(1).找到最小元素,放到队列头,队列头有序。以此类推
31 void SelectionSort(std::vector<int>& array);
32 // 堆排序. 时间复杂度O(nlogn),空间复杂度O(nlogn)
33 void HeapSort(std::vector<int>& array);
34 // 归并排序.时间复杂度O(nlogn),空间复杂度O(nlogn)
35 void MergeSort(std::vector<int>& array, int begin, int end);
36 // -----------------非比较排序----------------
37 // 计数排序.时间复杂度O(n+k),空间复杂度O(n+k),k是整数取值范围.快过任何比较排序算法,但是对空间要求较高,适用于有限小范围的区域
38 void CountingSort(std::vector<int>& array, int max = 100);
39 // 桶排序,是计数排序的升级版本。时间复杂度O(n+k) - O(n2),空间复杂度O(n+k),k是整数取值范围.快过任何比较排序算法,但是对空间要求较高,适用于有限小范围的区域
40 // 计数排序申请的空间比较大,如果分散不均匀,很多空间未访问,会造成浪费。桶排序取出最大值和最小值的差值,划分成若干个 连续+范围递增 的数组,每个数组进行内部排序
41 void BucketSort(std::vector<int>& array);
42 // 基数排序.时间复杂度O(n*k),空间复杂度O(n+k)
43 void RadixSort(std::vector<int>& array);
44
45 int main() {
46 // BubbleSort(g_array);
47 // QuickSort(g_array, 0, g_array.size() - 1);
48 // InsertionSort2(g_array);
49 // ShellSort2(g_array);
50 // SelectionSort(g_array);
51 // HeapSort(g_array);
52 // MergeSort(g_array, 0, g_array.size() - 1);
53 // CountingSort(g_array);
54 // BucketSort(g_array);
55 RadixSort(g_array);
56 ShowArray(g_array);
57 return 0;
58 }
59
60 void BubbleSort(std::vector<int>& array) {
61 const size_t sz = array.size();
62 if (sz <= 1) {
63 return;
64 }
65 for (int i = 0; i < sz; ++i) {
66 for (int j = 0; j < sz - i - 1; ++j) {
67 if (array[j] > array[j + 1]) {
68 Swap(array, j, j + 1);
69 }
70 }
71 }
72 }
73
74 void QuickSort(std::vector<int>& nums, int l ,int r) {
75 if (l < r) {
76 const int target = nums[l];
77 int b = l + 1;
78 int e = r;
79 while (b < e)
80 {
81 if (nums[b] >= target && nums[e] < target) {
82 Swap(nums, b, e);
83 }
84 if (nums[b] < target) {
85 b++;
86 }
87 if (nums[e] >= target) {
88 e--;
89 }
90 }
91 if (nums[l] > nums[b]) {
92 Swap(nums, b, l);
93 }
94 QuickSort(nums, l, b - 1);
95 QuickSort(nums, b, r);
96 }
97 }
98
99 void InsertionSort1(std::vector<int> &array) {
100 const size_t sz = array.size();
101 if (sz <= 1) {
102 return;
103 }
104 for (int i = 1; i < sz; ++i) {
105 const int target = array[i];
106 int j = i;
107 for (; j > 0; --j) {
108 if (array[j - 1] <= target) {
109 break;
110 }
111 }
112 for (int k = i; k > j; --k) {
113 array[k] = array[k - 1];
114 }
115 array[j] = target;
116 }
117 }
118
119 void InsertionSort2(std::vector<int> &array) {
120 const size_t sz = array.size();
121 if (sz <= 1) {
122 return;
123 }
124 for (int i = 1; i < sz; ++i) {
125 const int target = array[i];
126 int j = i;
127 for (; j > 0 && array[j] < array[j - 1]; --j) {
128 Swap(array, j, j -1);
129 }
130 array[j] = target;
131 }
132 }
133
134 void ShellSort1(std::vector<int> &array) {
135 const size_t sz = array.size();
136 if (sz <= 1) {
137 return;
138 }
139 for (int gap = sz/2; gap > 0; gap = gap/2) {
140 for (int i = 0; i < gap; ++i) {
141 // 对每组增量进行插入排序
142 for (int j = i + gap; j < sz; j += gap) {
143 const int target = array[j];
144 int k = j;
145 for (; k > 0; k -= gap) {
146 if (array[k - gap] < target) {
147 break;
148 }
149 }
150 for (int l = j; l > k; l -= gap) {
151 array[l] = array[l - gap];
152 }
153 array[k] = target;
154 }
155 }
156 }
157 }
158
159 void ShellSort2(std::vector<int> &array) {
160 const size_t sz = array.size();
161 if (sz <= 1) {
162 return;
163 }
164 for (int gap = sz/2; gap > 0; gap = gap/2) {
165 for (int i = gap; i < sz; ++i) {
166 const int target = array[i];
167 int j = i;
168 for (; j >= gap && array[j] < array[j - gap]; j = j - gap) {
169 Swap(array, j, j - gap);
170 }
171 array[j] = target;
172 }
173 }
174 }
175
176 void SelectionSort(std::vector<int> &array) {
177 const size_t sz = array.size();
178 if (sz <= 1) {
179 return;
180 }
181 for (int i = 0; i < sz; ++i) {
182 int min = array[i];
183 int index = i;
184 for (int j = i; j < sz; ++j) {
185 if (array[j] < min) {
186 min = array[j];
187 index = j;
188 }
189 }
190 Swap(array, index, i);
191 }
192 }
193
194 void AdjustHeap(std::vector<int> &array, int parent, int sz) {
195 if (sz <= 1) {
196 return;
197 }
198 const int left = parent*2 + 1;
199 if (left >= sz) {
200 return;
201 } else {
202 const int right = parent*2 + 2;
203 if (right >= sz) {
204 if (array[parent] < array[left]) {
205 Swap(array, parent, left);
206 AdjustHeap(array, left, sz);
207 }
208 } else {
209 int max = array[right] < array[left] ? left : right;
210 if (array[parent] < array[max]) {
211 Swap(array, parent, max);
212 AdjustHeap(array, max, sz);
213 }
214 }
215 }
216 }
217
218 void HeapSort(std::vector<int> &array) {
219 const size_t sz = array.size();
220 if (sz <= 1) {
221 return;
222 }
223 // 构建大顶堆
224 for (int i = sz - 1; i > 0; i = i - 2) {
225 const int parent = i/2;
226 AdjustHeap(array, parent, sz);
227 }
228 // 交换最大元素到末尾
229 for (int j = 1; j <= sz; ++j) {
230 Swap(array, 0, sz - j);
231 AdjustHeap(array, 0, sz - j);
232 }
233 }
234
235 std::vector<int> temp;
236 void MergeSort(std::vector<int> &array, int begin, int end) {
237 const size_t sz = end - begin + 1;
238 if (sz <= 1) {
239 return;
240 }
241 int mid = (begin + end)/2;
242 MergeSort(array, begin, mid);
243 MergeSort(array, mid + 1, end);
244
245 int left = begin;
246 int right = mid + 1;
247
248 temp.resize(sz);
249 for (int i = begin; i <= end; ++i) {
250 int min;
251 if (left > mid) {
252 min = right++;
253 } else if (right > end) {
254 min = left++;
255 } else if (array[left] < array[right]) {
256 min = left++;
257 } else {
258 min = right++;
259 }
260 temp.push_back(array[min]);
261 }
262 for (int i = begin; i <= end; ++i) {
263 array[i] = temp[i - begin];
264 }
265 }
266
267 void CountingSort(std::vector<int> &array, int max) {
268 const size_t sz = array.size();
269 if (sz <= 1) {
270 return;
271 }
272 std::vector<int> count(max, 0);
273 for (int i = 0; i < sz; ++i) {
274 count[array[i]]++;
275 }
276 array.clear();
277 array.reserve(sz);
278 for (int j = 0; j < max; ++j) {
279 while (count[j]-- > 0) {
280 array.push_back(j);
281 }
282 }
283 }
284
285 void BucketSort(std::vector<int> &array) {
286 const size_t sz = array.size();
287 if (sz <= 1) {
288 return;
289 }
290 int max = std::numeric_limits<int>::min();
291 int min = std::numeric_limits<int>::max();
292 for (int i = 0; i < sz; ++i) {
293 if (array[i] > max) {
294 max = array[i];
295 }
296 if (array[i] < min) {
297 min = array[i];
298 }
299 }
300 const int bucketCount = 1;
301 std::vector<std::vector<int>> buckets;
302 buckets.resize(bucketCount);
303 const int bucketRangeIncrease = (max - min)/bucketCount + 1; // 这里+1很重要
304 for (int j = 0; j < sz; ++j) {
305 // 采用相对法,保证(array[j] - min)一定>=0。如果带排序内有负数,则下标计算出来是负值
306 buckets[(array[j] - min)/bucketRangeIncrease].push_back(array[j]);
307 }
308 array.clear();
309 for (int k = 0; k < bucketCount; ++k) {
310 if (buckets[k].empty()) {
311 continue;
312 }
313 InsertionSort1(buckets[k]);
314 for (int i = 0; i < buckets[k].size(); ++i) {
315 array.push_back(buckets[k][i]);
316 }
317 }
318 }
319
320 void RadixSort(std::vector<int> &array) {
321 const size_t sz = array.size();
322 if (sz <= 1) {
323 return;
324 }
325 int max = std::numeric_limits<int>::min();
326 for (int i = 0; i < sz; ++i) {
327 if (max < array[i]) {
328 max = array[i];
329 }
330 }
331 int count = 1;
332 int radix = 1;
333 while (max / radix > 10) {
334 radix *= 10;
335 count++;
336 }
337 std::vector<std::vector<int>> buckets;
338 for (int j = 1; j <= count; ++j) {
339 buckets.clear();
340 buckets.resize(10); // 0 - 9
341 radix = 1;
342 for (int k = 1; k < j; ++k) {
343 radix *= 10;
344 }
345 for (int i = 0; i < sz; ++i) {
346 int index = (array[i] / radix) % 10;
347 buckets[index].push_back(array[i]);
348 }
349 array.clear();
350 array.reserve(sz);
351 for (int l = 0; l < 10; ++l) {
352 for (int i = 0; i < buckets[l].size(); ++i) {
353 array.push_back(buckets[l][i]);
354 }
355 }
356 }
357 }