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

  • 相关阅读:
    jmeter BeanShell内置变量的基本使用
    自定义 resetCSS
    JavaScript + html 制作钟表
    JavaScript 实现放大镜效果
    JavaScript 实现拖拽
    JavaScript 阻止事件的默认行为
    JavaScript 事件冒泡
    JavaScript 鼠标事件、键盘事件
    JavaScript window.location
    JavaScript 中document.getElementsByClassName() 在ie8以下不兼容问题
  • 原文地址:https://www.cnblogs.com/richselian/p/2179152.html
Copyright © 2020-2023  润新知