更高效的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重新设计了应用跨集群故障迁移功能,实现了基于污点的故障驱逐机制,并提供平滑的故障迁移过程,可以有效保障服务迁移过程的连续性(不断服). 本文分享自华为云社区 ...
随机推荐
- MAC升级node及npm
清除node.js的cache: sudo npm cache clean -f 安装 n 工具,这个工具是专门用来管理node.js版本的,别怀疑这个工具的名字,是他是他就是他,他的名字就是 &qu ...
- git上传的文件夹为空的时候
1,先删除空的文件夹 参考:https://www.cnblogs.com/wang715100018066/p/9694532.html 2,这个只能说是技巧不能说是方法,原理是在每个空文件夹新建一 ...
- HDU 2199 Can you solve this equation(二分答案)
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- 去除select边框和三角-----appearance:none
今天发现一个比较有意思的属性,appearance:none 可能有朋友不认识,但是有一个标签你肯定认识:select. 这个标签的样式是这样的: 一般情况下,我们所使用的border:0; 去除边框 ...
- kvm/qemu虚拟机桥接网络创建与配置
首先阐述一下kvm与qemu的关系,kvm是修改过的qemu,而且使用了硬件支持的仿真,仿真速度比QEMU快. 配置kvm/qemu的网络有两种方法.其一,默认方式为用户模式网络(Usermode N ...
- 【CF886E】Maximum Element DP
[CF886E]Maximum Element 题意:小P有一个1-n的序列,他想找到整个序列中最大值的出现位置,但是他觉得O(n)扫一遍太慢了,所以它采用了如下方法: 1.逐个遍历每个元素,如果这个 ...
- MONGOOSE – 让NODE.JS高效操作MONGODB(转载)
Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用. ...
- php小记
php获取日期: date_default_timezone_set('PRC'); //默认时区 "今天:",date("Y-m-d",time()),&qu ...
- 托管调试助手 "DisconnectedContext":“上下文 0xf20540 已断开连接... 请确保在应用程序全部完成 RuntimeCallableWrapper (表示其内部的 COM 组件)之前,所有 COM 上下文/单元/线程都保持活动状态并可用于上下文转换
最近做一个winForm的小工具,用到了 ManagementObjectSearcher/ManagementClass 和 WndProc ,涉及到对 移动设备的检测. 窗体加载时会执行一个 Re ...
- ubuntu 添加用户到已存在的组
sudo adduser 用户名 组名 sudo minicom –s 配置 minicom访问ttyUSB0没权限,发现属于dialout 组 james@james-OptiPlex-380: ...