排序算法之 Merge Sort

Merge Sort (cpp_cmerge_sort.cc)
================================================================================
最好时间复杂度  O(nlogn)
平均时间复杂度  O(nlogn)
最坏时间复杂度  O(nlogn)
空间复杂度    O(n)
是否稳定     是

  Merge Sort是归并排序的递归(自顶向下)实现,将序列分为左右两个等长(或长度相差1)的子序列,首先对两个子序列进行递归操作使它们成为有序序列,然后对这两个有序子序列进行Merge操作,得到完整的已排序序列。
  自顶向下归并和自底向上归并排序的特点完全相同,自顶向下归并中的序列等分操作在理论上要略优于自底向上归并的长度倍增操作(倍增操作的最后一轮会出现一个长序列和一个短序列进行Merge的现象),但递归调用也在一定程度上影响了算法的速度,所以在测试中两个算法所需的时间几乎相等。

 1 #include <cstdio>
2 #include <cstdlib>
3 #include <ctime>
4
5 static unsigned int set_times = 0;
6 static unsigned int cmp_times = 0;
7
8 template<typename item_type> void setval(item_type& item1, item_type& item2) {
9 set_times += 1;
10 item1 = item2;
11 return;
12 }
13
14 template<typename item_type> int compare(item_type& item1, item_type& item2) {
15 cmp_times += 1;
16 return item1 < item2;
17 }
18
19 template<typename item_type> void swap(item_type& item1, item_type& item2) {
20 item_type item3;
21
22 setval(item3, item1);
23 setval(item1, item2);
24 setval(item2, item3);
25 return;
26 }
27
28 template<typename item_type> void merge_sort_pass(
29 item_type* array, item_type* temp_array, int l, int r) {
30 int m = (l + r) / 2;
31 int pos1 = l;
32 int pos2 = m;
33 int ins_pos = 0;
34
35 if(r - l > 1) {
36 merge_sort_pass(array, temp_array, l, m);
37 merge_sort_pass(array, temp_array, m, r);
38
39 while(pos1 < m && pos2 < r) {
40 if(compare(array[pos2], array[pos1])) {
41 setval(temp_array[ins_pos++], array[pos2++]);
42 } else {
43 setval(temp_array[ins_pos++], array[pos1++]);
44 }
45 }
46
47 while(pos1 < m) setval(temp_array[ins_pos++], array[pos1++]);
48 while(pos2 < r) setval(temp_array[ins_pos++], array[pos2++]);
49 while(ins_pos > 0) {
50 setval(array[--r], temp_array[--ins_pos]);
51 }
52 }
53 return;
54 }
55 template<typename item_type> void merge_sort(item_type* array, int size) {
56 item_type* temp_array = new item_type[size];
57
58 merge_sort_pass(array, temp_array, 0, size);
59 delete[] temp_array;
60 return;
61 }
62
63 int main(int argc, char** argv) {
64 int capacity = 0;
65 int size = 0;
66 int i;
67 clock_t clock1;
68 clock_t clock2;
69 double data;
70 double* array = NULL;
71
72 // generate randomized test case
73 while(scanf("%lf", &data) == 1) {
74 if(size == capacity) {
75 capacity = (size + 1) * 2;
76 array = (double*)realloc(array, capacity * sizeof(double));
77 }
78 array[size++] = data;
79 }
80
81 // sort
82 clock1 = clock();
83 merge_sort(array, size);
84 clock2 = clock();
85
86 // output test result
87 fprintf(stderr, "merge_sort:\t");
88 fprintf(stderr, "time %.2lf\t", (double)(clock2 - clock1) / CLOCKS_PER_SEC);
89 fprintf(stderr, "cmp_per_elem %.2lf\t", (double)cmp_times / size);
90 fprintf(stderr, "set_per_elem %.2lf\n", (double)set_times / size);
91 for(i = 0; i < size; i++) {
92 fprintf(stdout, "%lf\n", array[i]);
93 }
94 free(array);
95 return 0;
96 }

原文地址:https://www.cnblogs.com/richselian/p/2179133.html