博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序算法之 Non-recursive Merge Sort
阅读量:4618 次
发布时间:2019-06-09

本文共 3061 字,大约阅读时间需要 10 分钟。

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 
2 #include
3 #include
4 5 static unsigned int set_times = 0; 6 static unsigned int cmp_times = 0; 7 8 template
void setval(item_type& item1, item_type& item2) {
9 set_times += 1; 10 item1 = item2; 11 return; 12 } 13 14 template
int compare(item_type& item1, item_type& item2) {
15 cmp_times += 1; 16 return item1 < item2; 17 } 18 19 template
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
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 }

 

转载于:https://www.cnblogs.com/richselian/archive/2011/09/16/2179137.html

你可能感兴趣的文章
死磕 java同步系列之AQS起篇
查看>>
利用Lucene把文本的字体格式进行改动,然后输出到一个新的文件里
查看>>
[Openstack] Expecting an auth URL via either --os-auth-url or env[OS_AUTH_URL]
查看>>
How to Create Modifiers Using the API QP_MODIFIERS_PUB.PROCESS_MODIFIERS
查看>>
待飞笔记(第一天 )
查看>>
用Winrar批量解压缩有密码文件方法,只需输入一次密码
查看>>
解惑好文:移动端H5页面高清多屏适配方案
查看>>
traefik添加多证书
查看>>
PhantomJs 笔记
查看>>
js设计模式--语言类型
查看>>
C#多线程之二:ManualResetEvent和AutoResetEvent
查看>>
Java如何获取系统cpu、内存、硬盘信息
查看>>
忽略UserInterfaceState.xcuserstate
查看>>
ReactNative--Flexbox布局
查看>>
java实现读取文件大全
查看>>
[Cordova] 无法显示Alert视窗
查看>>
借助过度区选择阈值
查看>>
价格正则
查看>>
对for 循环的初认识
查看>>
评论列表显示及排序,个人中心显示
查看>>