Slow Sort (cpp_slow_sort.cc)
================================================================================
最好时间复杂度 O(nlogn)
平均时间复杂度 O(nlogn)
最坏时间复杂度 O(n^2)
空间复杂度 O(n)
是否稳定 是
Slow Sort是我自创的一种排序法,原理和也是使用折半查找的插入排序并减少调整位置所需的时间,与Library Sort不同的是我采用的是链式的方法,使用一个辅助next域支持原数组在内部进行交换排序,结构比Library Sort要紧凑,空间复杂度因子要比Library Sort小。和Library Sort一样,在输入正序和倒序时也出现O(n^2)的最坏情况。
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 slow_sort(item_type* array, int size) {
29 int* next = new int[size];
30 int i;
31 int m;
32 int l;
33 int r;
34 int sorted_size;
35
36 for(i = size - 1; i > 0; i--) {
37 if(compare(array[i], array[i - 1])) {
38 swap(array[i], array[i - 1]);
39 }
40 }
41 next[0] = -1;
42 sorted_size = 1;
43
44 for(i = 1; i < size; i++) {
45 l = 1;
46 r = sorted_size - 1;
47
48 while(l <= r) {
49 m = (l + r) / 2;
50 compare(array[i], array[m]) ? r = m - 1 : l = m + 1;
51 }
52 while(next[r] >= 0 && compare(array[next[r]], array[i])) {
53 r = next[r];
54 }
55 next[i] = next[r];
56 next[r] = i;
57
58 if(i > sorted_size * 2 || i == size - 1) {
59 for(r = 0, l = 0; l >= 0; l = m) {
60 m = next[l];
61 next[l] = r++;
62 }
63 for(l = 0; l <= i; l++) {
64 while(l != next[l]) {
65 swap(array[l], array[next[l]]);
66 m = next[next[l]];
67 next[next[l]] = next[l];
68 next[l] = m;
69 }
70 }
71 for(l = 0; l < i; l++) {
72 next[l] = l + 1;
73 }
74 next[i] = -1;
75 sorted_size = i + 1;
76 }
77 }
78 delete[] next;
79 return;
80 }
81
82 int main(int argc, char** argv) {
83 int capacity = 0;
84 int size = 0;
85 int i;
86 clock_t clock1;
87 clock_t clock2;
88 double data;
89 double* array = NULL;
90
91 // generate randomized test case
92 while(scanf("%lf", &data) == 1) {
93 if(size == capacity) {
94 capacity = (size + 1) * 2;
95 array = (double*)realloc(array, capacity * sizeof(double));
96 }
97 array[size++] = data;
98 }
99
100 // sort
101 clock1 = clock();
102 slow_sort(array, size);
103 clock2 = clock();
104
105 // output test result
106 fprintf(stderr, "slow_sort:\t");
107 fprintf(stderr, "time %.2lf\t", (double)(clock2 - clock1) / CLOCKS_PER_SEC);
108 fprintf(stderr, "cmp_per_elem %.2lf\t", (double)cmp_times / size);
109 fprintf(stderr, "set_per_elem %.2lf\n", (double)set_times / size);
110 for(i = 0; i < size; i++) {
111 fprintf(stdout, "%lf\n", array[i]);
112 }
113 free(array);
114 return 0;
115 }