排序算法之 Library Sort

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

  Library Sort基于折半查找的插入排序,插入时在元素附近空出一定位置,这样推入后移动元素的复杂度由原来的O(n)下降为平均O(1),于是整个算法的复杂度达到O(nlogn)。当输入正序或倒序时,插入点都在同一位置,“留空位”的策略失效,这时就出现最坏复杂度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 library_sort(item_type* array, int size) {
29 item_type* bucket = new item_type[size * 3];
30 int* filled = new int[size * 3];
31 int i;
32 int l;
33 int m;
34 int r;
35 int ins_pos;
36 int bucket_size;
37 item_type tempitem;
38
39 if(size > 0) {
40 for(i = 1; i < size * 3; i++) {
41 filled[i] = 0;
42 }
43 filled[0] = 1;
44 bucket[0] = array[0];
45 bucket_size = 1;
46 }
47
48 for(i = 1; i < size; i++) {
49 l = 0;
50 r = bucket_size - 1;
51
52 while(l <= r) {
53 m = (l + r) / 2;
54 compare(array[i], bucket[m * 3]) ? r = m - 1 : l = m + 1;
55 }
56
57 ins_pos = (r >= 0) ? r * 3 + 1 : 0;
58 setval(tempitem, array[i]);
59 while(filled[ins_pos]) {
60 if(compare(tempitem, bucket[ins_pos])) {
61 swap(bucket[ins_pos], tempitem);
62 }
63 ins_pos++;
64 }
65 setval(bucket[ins_pos], tempitem);
66 filled[ins_pos] = 1;
67
68 if(i == bucket_size * 2 - 1) {
69 r = bucket_size * 6 - 3;
70 l = bucket_size * 4 - 3;
71 while(l >= 0) {
72 if(filled[l]) {
73 filled[l] = 0;
74 filled[r] = 1;
75 setval(bucket[r], bucket[l]);
76 r -= 3;
77 }
78 l -= 1;
79 }
80 bucket_size = i + 1;
81 }
82 }
83
84 for(i = 0, l = 0; l < size * 3; l++) {
85 if(filled[l]) {
86 setval(array[i++], bucket[l]);
87 }
88 }
89 return;
90 }
91
92 int main(int argc, char** argv) {
93 int capacity = 0;
94 int size = 0;
95 int i;
96 clock_t clock1;
97 clock_t clock2;
98 double data;
99 double* array = NULL;
100
101 // generate randomized test case
102 while(scanf("%lf", &data) == 1) {
103 if(size == capacity) {
104 capacity = (size + 1) * 2;
105 array = (double*)realloc(array, capacity * sizeof(double));
106 }
107 array[size++] = data;
108 }
109
110 // sort
111 clock1 = clock();
112 library_sort(array, size);
113 clock2 = clock();
114
115 // output test result
116 fprintf(stderr, "library_sort:\t");
117 fprintf(stderr, "time %.2lf\t", (double)(clock2 - clock1) / CLOCKS_PER_SEC);
118 fprintf(stderr, "cmp_per_elem %.2lf\t", (double)cmp_times / size);
119 fprintf(stderr, "set_per_elem %.2lf\n", (double)set_times / size);
120 for(i = 0; i < size; i++) {
121 fprintf(stdout, "%lf\n", array[i]);
122 }
123 free(array);
124 return 0;
125 }

 

posted on 2011-09-16 19:12  RichSelian  阅读(802)  评论(0编辑  收藏  举报

导航