zoukankan      html  css  js  c++  java
  • 排序算法之 Smooth Sort

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

      Smooth Sort基本思想和Heap Sort相同,但Smooth Sort使用的是一种由多个堆组成的优先队列,这种优先队列在取出最大元素后剩余元素可以就地调整成优先队列,所以Smooth Sort不用像Heap Sort那样反向地构建堆,在数据基本有序时可以达到O(n)复杂度。Smooth Sort算法在维基百科上有详细介绍。
      Smooth Sort是所有算法中时间复杂度理论值最好的,但由于Smooth Sort所用的优先队列是基于一种不平衡的结构,复杂度因子很大,所以该算法的实际效率并不是很好。

      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 static const unsigned int leonardo[] = {
    29 1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973,
    30 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785,
    31 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 11405773,
    32 18454929, 29860703, 48315633, 78176337, 126491971, 204668309, 331160281,
    33 535828591, 866988873, 1402817465, 2269806339u, 3672623805u,
    34 };
    35
    36 template<typename item_type> inline void smooth_sort_fix(
    37 item_type* array, int current_heap, int level_index, int* levels) {
    38 int prev_heap;
    39 int max_child;
    40 int child_heap1;
    41 int child_heap2;
    42 int current_level;
    43
    44 while(level_index > 0) {
    45 prev_heap = current_heap - leonardo[levels[level_index]];
    46 if(compare(array[current_heap], array[prev_heap])) {
    47 if(levels[level_index] > 1) {
    48 child_heap1 = current_heap - 1 - leonardo[levels[level_index] - 2];
    49 child_heap2 = current_heap - 1;
    50 if(compare(array[prev_heap], array[child_heap1])) break;
    51 if(compare(array[prev_heap], array[child_heap2])) break;
    52 }
    53 swap(array[current_heap], array[prev_heap]);
    54 current_heap = prev_heap;
    55 level_index -= 1;
    56 } else break;
    57 }
    58
    59 current_level = levels[level_index];
    60 while(current_level > 1) {
    61 max_child = current_heap;
    62 child_heap1 = current_heap - 1 - leonardo[current_level - 2];
    63 child_heap2 = current_heap - 1;
    64
    65 if(compare(array[max_child], array[child_heap1])) max_child = child_heap1;
    66 if(compare(array[max_child], array[child_heap2])) max_child = child_heap2;
    67 if(max_child == child_heap1) {
    68 swap(array[current_heap], array[child_heap1]);
    69 current_heap = child_heap1;
    70 current_level -= 1;
    71 }
    72 else if(max_child == child_heap2) {
    73 swap(array[current_heap], array[child_heap2]);
    74 current_heap = child_heap2;
    75 current_level -= 2;
    76 } else break;
    77 }
    78 return;
    79 }
    80
    81 template<typename item_type> void smooth_sort(item_type* array, int size) {
    82
    83 int levels[64] = {1};
    84 int toplevel = 0;
    85 int i;
    86
    87 for(i = 1; i < size; i++) {
    88 if(toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
    89 toplevel -= 1;
    90 levels[toplevel] += 1;
    91 } else if(levels[toplevel] != 1) {
    92 toplevel += 1;
    93 levels[toplevel] = 1;
    94 } else {
    95 toplevel += 1;
    96 levels[toplevel] = 0;
    97 }
    98 smooth_sort_fix(array, i, toplevel, levels);
    99 }
    100
    101 for(i = size - 2; i > 0; i--) {
    102 if(levels[toplevel] <= 1) {
    103 toplevel -= 1;
    104 } else {
    105 levels[toplevel] -= 1;
    106 levels[toplevel + 1] = levels[toplevel] - 1;
    107 toplevel += 1;
    108
    109 smooth_sort_fix(array, i - leonardo[levels[toplevel]], toplevel - 1, levels);
    110 smooth_sort_fix(array, i, toplevel, levels);
    111 }
    112 }
    113 return;
    114 }
    115
    116 int main(int argc, char** argv) {
    117 int capacity = 0;
    118 int size = 0;
    119 int i;
    120 clock_t clock1;
    121 clock_t clock2;
    122 double data;
    123 double* array = NULL;
    124
    125 // generate randomized test case
    126 while(scanf("%lf", &data) == 1) {
    127 if(size == capacity) {
    128 capacity = (size + 1) * 2;
    129 array = (double*)realloc(array, capacity * sizeof(double));
    130 }
    131 array[size++] = data;
    132 }
    133
    134 // sort
    135 clock1 = clock();
    136 smooth_sort(array, size);
    137 clock2 = clock();
    138
    139 // output test result
    140 fprintf(stderr, "smooth_sort:\t");
    141 fprintf(stderr, "time %.2lf\t", (double)(clock2 - clock1) / CLOCKS_PER_SEC);
    142 fprintf(stderr, "cmp_per_elem %.2lf\t", (double)cmp_times / size);
    143 fprintf(stderr, "set_per_elem %.2lf\n", (double)set_times / size);
    144 for(i = 0; i < size; i++) {
    145 fprintf(stdout, "%lf\n", array[i]);
    146 }
    147 free(array);
    148 return 0;
    149 }

  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/richselian/p/2179148.html
Copyright © 2011-2022 走看看