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

  • 相关阅读:
    SQL Server 连接字符串和身份验证 学习
    何時需要重启 OFBiz
    开源软件文档网址
    OFBIZ 10.04 开发环境搭建(ofbiz+mysql+eclipse)
    ofbiz 之minilang解析
    ofbiz之entity实体写法
    ofbiz多表外键关联查询
    ofbiz学习地址
    配置文件中的mime-mapping元素(ofbiz/framework/catalina/config/mime-type)(
    SQL连接 自我学习,跑完秒懂
  • 原文地址:https://www.cnblogs.com/richselian/p/2179137.html
Copyright © 2020-2023  润新知