• 排序算法之 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 }

  • 相关阅读:
    oracle nvl,to_char 函数(二)
    GridView的使用技巧
    asp.net应用程序性能的提高方案
    浅谈 ViewState
    最为关心的问题,hbase查询一条数据的过程.
    HBase的弊端。
    拙建:(mapreduce 如何来分步统计词频)
    终于找到hbase分布式存储数据的方式.
    迷局一般的openjdk6jdk!
    IT事业不好走,大家在虚拟的世界,记得回到真实的世界,不然你将会成为下一个张孝祥.
  • 原文地址:https://www.cnblogs.com/richselian/p/2179148.html
Copyright © 2020-2023  润新知