更高效的MergeSort--稍微优化
0. 简介
本文简要介绍一下比传统MergeSort更高效的算法,在原来的算法Merge基础上,少发生一半拷贝。欢迎探讨,感谢阅读。
原文链接如下:http://loverszhaokai.com/posts/More-Efficient-MergeSort/
1. Reference
原文链接
Introuction to Algorithms
https://github.com/loverszhaokai/ALG/blob/master/src/sort.cc
2. MergeSort
void merge(int a[], int b[], const int left, const int middle,
const int right) {
int li, ri, i;
li = left;
ri = middle + 1;
i = 0;
while (li <= middle && ri <= right) {
if (a[li] < a[ri])
b[i++] = a[li++];
else
b[i++] = a[ri++];
}
while (li <= middle)
b[i++] = a[li++];
while (ri <= right)
b[i++] = a[ri++];
}
void copy(int dst[], int dleft, int src[], int sleft, int sright) {
memcpy(dst + dleft, src + sleft,
sizeof(int) * (sright - sleft + 1));
}
void _merge_sort(int a[], int b[], const int left, const int right) {
if (left >= right)
return;
int middle = (left + right) / 2;
_merge_sort(a, b, left, middle);
_merge_sort(a, b, middle + 1, right);
merge(a, b, left, middle, right);
copy(a, left, b, 0, right - left);
}
void merge_sort(int a[], const int size) {
int *b = (int *)malloc(size * sizeof(int));
_merge_sort(a, b, 0, size - 1);
free(b);
}
3. More Efficient MergeSort
We can save some time by copy half when merge()
. In merge()
, we copy from
left to right, but in MergeKai()
we can only copy from left to
middle. The merge()
has NlgN
duplications which the MergeKai()
has
1/2 * NlgN
duplications.
normal merge sort
more efficient merge sort
Just as the previous example, the efficient merge sort does not need to copy
1, 3, 7, 8
to the assit array.
// Merge the two list in [left, mid], and (mid, right]. Then, write
// the result to [left, right]
static void MergeKai(int a[], int assist[], const int left,
const int mid, const int right) {
int l = left;
int r = mid + 1;
int assist_index = 0;
// Copy [left, mid] to assit[0, mid - left]
memcpy(assist, a + left, (mid - left + 1) * sizeof(int));
while (assist_index <= mid - left && r <= right) {
if (assist[assist_index] <= a[r]) {
a[l++] = assist[assist_index++];
continue;
} else if (assist[assist_index] > a[r]) {
a[l++] = a[r++];
}
}
while (assist_index <= mid - left) {
a[l++] = assist[assist_index++];
}
while (r <= right) {
a[l++] = a[r++];
}
}
static void MergeSortKaiImpl(int a[], int assist[], const int left,
const int right) {
if (left >= right) {
return;
}
const int mid = (left + right) / 2;
MergeSortKaiImpl(a, assist, left, mid);
MergeSortKaiImpl(a, assist, mid + 1, right);
MergeKai(a, assist, left, mid, right);
}
void MergeSortKai(int a[], const int size) {
int* assist= (int *)malloc(size * sizeof(int));
MergeSortKaiImpl(a, assist, 0, size - 1);
free(assist);
}
4. Experiments
source:
https://github.com/loverszhaokai/ALG/blob/master/src/sort.cc
https://github.com/loverszhaokai/ALG/blob/master/test/sort_test.cc
result:
It takes 1524.61 ms to generate arrays: 1000000 * 20
Sort Function Total Run Time Array Size
---------------------------------------------------------------------
merge_sort_iteratively 826 ms 1000000 * 20
merge_sort 840 ms 1000000 * 20
MergeSortIterativelyKai 826 ms 1000000 * 20
MergeSortKai 809 ms 1000000 * 20
It takes 15028.2 ms to generate arrays: 10000000 * 20
Sort Function Total Run Time Array Size
---------------------------------------------------------------------
merge_sort_iteratively 8717 ms 10000000 * 20
merge_sort 8820 ms 10000000 * 20
MergeSortIterativelyKai 8425 ms 10000000 * 20
MergeSortKai 8389 ms 10000000 * 20
It takes 1929.31 ms to generate arrays: 100000 * 200
Sort Function Total Run Time Array Size
---------------------------------------------------------------------
merge_sort_iteratively 1245 ms 100000 * 200
merge_sort 1347 ms 100000 * 200
MergeSortIterativelyKai 1246 ms 100000 * 200
MergeSortKai 1275 ms 100000 * 200
更高效的MergeSort--稍微优化的更多相关文章
- 使jQuqer更高效的方法
讨论 jQuery 和 javascript 性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的 jQuery 和 javascript 代码.好的代码会带来速度 ...
- 如何使代码审查更高效【摘自InfoQ】
代码审查者在审查代码时有非常多的东西需要关注.一个团队需要明确对于自己的项目哪些点是重要的,并不断在审查中就这些点进行检查. 人工审查代码是十分昂贵的,因此尽可能地使用自动化方式进行审查,如:代码 ...
- 如何让windows更高效?
首先解释一下个标题: "让windows更高效,既指让windows更友好更优化,也指可以让使用windows来工作或学习的人更高效的工作学习." 解释下本文的动机: 指导我自己或 ...
- 更强、更稳、更高效:解读 etcd 技术升级的三驾马车
点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 陈星宇(宇慕 ...
- CesiumLab V1.4 分类3dtiles生成(倾斜单体化、楼层房间交互)我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了。不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化。就下面这个示例https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=
我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了.不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化.就下面这个示例 http ...
- [源码解析]为什么mapPartition比map更高效
[源码解析]为什么mapPartition比map更高效 目录 [源码解析]为什么mapPartition比map更高效 0x00 摘要 0x01 map vs mapPartition 1.1 ma ...
- 阿里面试:MySQL如何设计索引更高效?
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- K8s 如何提供更高效稳定的编排能力?K8s Watch 实现机制浅析
关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...
- Karmada v1.3:更优雅 更精准 更高效
摘要:最新发布的1.3版本中,Karmada重新设计了应用跨集群故障迁移功能,实现了基于污点的故障驱逐机制,并提供平滑的故障迁移过程,可以有效保障服务迁移过程的连续性(不断服). 本文分享自华为云社区 ...
随机推荐
- Openstack的网卡设置
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 最开始接触Openstack,这块是比较头疼的,不同的文档,设置都会有所差异,并 ...
- wireshark 表达式备忘录
参考资料: https://blog.csdn.net/wojiaopanpan/article/details/69944970 wireshark分两种表达式,一种是捕获表达式,这个是在捕获时用的 ...
- powerDesigner根据sql脚本来逆向生成pdm等模型
一.问题概述 网上一般的博文都是说要建立数据源的方式来逆向或者正向. 我这人比较懒得折腾,更喜欢通过sql脚本的方式来做. 二.步骤 File-->New Model--> 然后: 注意上 ...
- 调用TerminateProcess是无法触发DLL_PROCESS_DETACH的
当应用程序中调用TerminateProcess函数,对于在DllMain函数中处理DLL_PROCESS_DETACH的额外代码操作是无法被执行的.比如:释放资源.数据持久化等.
- MySQL知识小结
MySQL的知识面试中还是经常被问到的,简单的使用似乎无法达到面试官的要求,很多问题会关于Mysql存储引擎,所以这里还是需要系统学习一下Mysql的一些知识,面试过程中游刃有余. MySQL体系结构 ...
- Unity3D笔记十八 GL图像库
1.绘制2D图像的时需要使用GL.LoadOrtho()方法来将图形映射到平面中. 2.所有绘制相关的内容都要写在OnPostRender()方法中. 3.有关GL图像库的脚本需要绑定到Hierarc ...
- Node复制文件
本人开发过程中,经常遇到,要去拷贝模板到当前文件夹,经常要去托文件,为了省事,解决这个问题,写了一个node复制文件. // js/app.js:指定确切的文件名.// js/*.js:某个目录所有后 ...
- [转][darkbaby]任天堂传——失落的泰坦王朝(中)
TV游戏产业历史上曾有过太多表里不一的外交辞令,然而当年SQUARE和任天堂分道扬镳的真正原因确实如坂口博信在1996年2月29日的PS版 <FFVII>发表会上宣称的那样:“虽然之前有过 ...
- 2-sat入门(tarjan)hdu(3062)
hdu3062 Party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 小程序中的block
<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性. 因为 wx:if 是一个控制属性,需要将它添加到一个标签上.如果要一次性判断多个组件标签, ...