• 排序算法之 Nonrecursive Merge Sort


    Non-recursive Merge Sort (cpp_merge_sort.cc)
    ================================================================================
    最好时间复杂度  O(nlogn)
    平均时间复杂度  O(nlogn)
    最坏时间复杂度  O(nlogn)
    空间复杂度    O(n)
    是否稳定     是

       Non-recursive Merge Sort是归并排序的非递归(自底向上归并)实现,将序列视为长度为s的有序序列集合(初始时s=1),然后将有序序列两两进行Merge操作,得到长度为2s的有序序列集合,重复操作直到序列中只剩下一个有序序列时排序结束。
       Non-recursive Merge Sort在所有测试的算法中速度仅次于Quick Sort,在需要排序稳定性或者O(nlogn)最坏情况时是Quick Sort的一个很好的替代,但所需O(n)的空间复杂度是对算法速度和适用范围一个严重的制约。SGI-STL库中std::stable_sort()的内部实现就是Non-recursive Merge 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 template<typename item_type> void ncmerge_sort(item_type* array, int size) {
    29 int step_width;
    30 int ins_pos;
    31 int l;
    32 int m;
    33 int r;
    34 int pos1;
    35 int pos2;
    36 item_type* temp_array = new item_type[size];
    37
    38 for(step_width = 2; step_width < size * 2; step_width *= 2) {
    39 for(l = 0; l + step_width / 2 < size; l += step_width) {
    40 m = l + step_width / 2;
    41 r = m + step_width / 2 < size ? m + step_width / 2 : size;
    42
    43 pos1 = l;
    44 pos2 = m;
    45 ins_pos = 0;
    46 while(pos1 < m && pos2 < r) {
    47 if(compare(array[pos2], array[pos1])) {
    48 setval(temp_array[ins_pos++], array[pos2++]);
    49 } else {
    50 setval(temp_array[ins_pos++], array[pos1++]);
    51 }
    52 }
    53 while(pos1 < m) setval(temp_array[ins_pos++], array[pos1++]);
    54 while(pos2 < r) setval(temp_array[ins_pos++], array[pos2++]);
    55 while(ins_pos > 0) {
    56 setval(array[--r], temp_array[--ins_pos]);
    57 }
    58 }
    59 }
    60 delete[] temp_array;
    61 return;
    62 }
    63
    64 int main(int argc, char** argv) {
    65 int capacity = 0;
    66 int size = 0;
    67 int i;
    68 clock_t clock1;
    69 clock_t clock2;
    70 double data;
    71 double* array = NULL;
    72
    73 // generate randomized test case
    74 while(scanf("%lf", &data) == 1) {
    75 if(size == capacity) {
    76 capacity = (size + 1) * 2;
    77 array = (double*)realloc(array, capacity * sizeof(double));
    78 }
    79 array[size++] = data;
    80 }
    81
    82 // sort
    83 clock1 = clock();
    84 ncmerge_sort(array, size);
    85 clock2 = clock();
    86
    87 // output test result
    88 fprintf(stderr, "ncmerge_sort:\t");
    89 fprintf(stderr, "time %.2lf\t", (double)(clock2 - clock1) / CLOCKS_PER_SEC);
    90 fprintf(stderr, "cmp_per_elem %.2lf\t", (double)cmp_times / size);
    91 fprintf(stderr, "set_per_elem %.2lf\n", (double)set_times / size);
    92 for(i = 0; i < size; i++) {
    93 fprintf(stdout, "%lf\n", array[i]);
    94 }
    95 free(array);
    96 return 0;
    97 }

  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/richselian/p/2179137.html
Copyright © 2020-2023  润新知