《算法导论》读书笔记之排序算法—Merge Sort 归并排序算法
自从打ACM以来也算是用归并排序了好久,现在就写一篇博客来介绍一下这个算法吧 :)

图片来自维基百科,显示了完整的归并排序过程。例如数组{38, 27, 43, 3, 9, 82, 10}.
在算法导论讲分治算法一章的时候提到了归并排序。首先,归并排序是一个分治算法。
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,
即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
merg() 函数是用来合并两个已有序的数组. 是整个算法的关键。
那么归并排序有什么用处呢?
- 对数组中元素经行排序
- 对链表中元素经行排序,其它排序算法如堆排序和快速排序不能对链表排序 (参考我写的博客http://www.cnblogs.com/wushuaiyi/p/4558391.html)
- 可以求逆序数 (参考我写的博客http://www.cnblogs.com/wushuaiyi/p/4362149.html)
- 外排序
下面是我写的归并排序使用C++实现的一个版本:
#include <iostream>
using namespace std;
const int MAXN = ;
int a[MAXN], tmp[MAXN], n;
void Merge (int l, int m, int r) {
int i = l;
int j = m + ;
int k = l;
while (i <= m && j <= r) {
if (a[i] < a[j]) {
tmp[k++] = a[i++];
} else {
tmp[k++] = a[j++];
}
}
while (i <= m) {
tmp[k++] = a[i++];
}
while (j <= r) {
tmp[k++] = a[j++];
}
for (int i = l; i <= r; ++i)
a[i] = tmp[i];
}
void Merge_sort (int l, int r) {
if (l < r) {
int m = (l + r) >> ;
Merge_sort (l, m);
Merge_sort (m + , r);
Merge (l, m, r);
}
}
int main() {
std::ios::sync_with_stdio(false);
int i, j, t, k, u, c, v, p, numCase = ;
while (cin >> n) {
for (i = ; i < n; ++i) {
cin >> a[i];
}
Merge_sort(, n - );
for (i = ; i < n; ++i) {
cout << a[i] << endl;
}
}
return ;
}
归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,
每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。
因为归并排序每次都是在相邻的数据中进行操作,
所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)
也是效率比较高的。
《算法导论》读书笔记之排序算法—Merge Sort 归并排序算法的更多相关文章
- 算法导论-MIT笔记
第一部分 Analysis of Algorithms 算法分析是关于计算机程序性能(performance)和资源利用的理论研究 1 What's more important than perfo ...
- <算法图解>读书笔记:第2章 选择排序
第2章 选择排序 2.1 内存的工作原理 需要将数据存储到内存时,请求计算机提供存储空间,计算机会给一个存储地址.需要存储多项数据时,有两种基本方式-数组和链表 2.2 数组和链表 2.2.1 链表 ...
- 算法:合并排序(Merge Sort)
算法定义 合并排序是一种递归算法,思路如下: 如果源数组长度为 1,立即返回. 将源数组平分为两个新数组:Left 和 Right. 对 Left 执行递归排序. 对 Right 执行递归排序. 将排 ...
- 数据结构与算法JavaScript 读书笔记
由于自己在对数组操作这块比较薄弱,然后经高人指点,需要好好的攻读一下这本书籍,原本想这个书名就比较高深,这下不好玩了.不过看着看着突然觉得讲的东西都比较基础.不过很多东西,平时还是没有注意到,故写出读 ...
- STL源码剖析读书笔记--第6章&第7章--算法与仿函数
老实说,这两章内容还蛮多的,但是其实在应用中一点点了解比较好.所以我决定这两张在以后使用过程中零零散散地总结,这个时候就说些基本概念好了.实际上,这两个STL组件都及其重要,我不详述一方面是自己偷懒, ...
- 《java并发编程实战》读书笔记12--原子变量,非阻塞算法,CAS
第15章 原子变量与非阻塞同步机制 近年来,在并发算法领域的大多数研究都侧重于非阻塞算法,这种算法用底层的原子机器指令(例如比较并交换指令)代替锁老确保数据在并发访问中的一致性. 15.1 锁的劣势 ...
- <数据挖掘导论>读书笔记7 Apriori算法
Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法.其核心是基于两阶段频集思想的递推算法.该关联规则在分类上属于单维.单层.布尔关联规则.在这里,所有支持度大于最小支持度的项集称为频繁项 ...
- <数据挖掘导论>读书笔记5关联分析的基本概念和算法
关联规则的强度可以用support度和confidence(置信)度来度量 关联规则发现 给定事务的集合T,关联规则发现是指找出支持度大于等于minsup并且置信度大于等于minconf的所有规则, ...
- 《java数据结构和算法》读书笔记
大学时并不是读计算机专业的, 之前并没有看过数据结构和算法,这是我第一次看. 从数据结构方面来说: 数组:最简单,遍历.查找很快:但是大小固定,不利于扩展 ...
随机推荐
- Android多线程任务优化1:探讨AsyncTask的缺陷
AsyncTask还有别的缺陷,在生成listview的时候,如果adapter里面的count动态改变的话,不能使用AsyncTask,只能使用Thread+Handler,否则会出现如下错误 j ...
- POJ 3080 Blue Jeans(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...
- 国产编程语言R++ V1.5发布
R++ v1.5内核改动较大,下面是一些主要变化: 1.使用PJIT(Pseudocode Just-In-Time),编译速度大幅提高,但运行效率远远不如C++,不过R++将在下一版本支持RJIT( ...
- 拥抱开源,怎样关注Linux Kernel 邮件列表?
现在开源如此火爆.以至于张口闭口不提到都仿佛不是搞IT 的.那么怎样拥抱开源?本文适合刚開始学习的人,如有大神至此,goto exit ! 一.怎样增加开源 以Linux 为例,这么一个成功的开源项目 ...
- BootStrap 智能表单系列 九 表单图片上传的支持
本章介绍如何在生成表单后,可以支持上传图片后可以及时预览图片 代码如下(连接地址:https://github.com/xiexingen/Bootstrap-SmartForm/blob/maste ...
- Spring注解与Spring与Struts2整合
@Component @Controller @Service @Repository 四大注解作用基本一样,只是表象在不同层面 @Resource @Scope Struts2与Spring整合:1 ...
- Linux学习之Shell编程基础
转自:http://my.oschina.net/itblog/blog/204410 1 语法基本介绍1.1 开头 程序必须以下面的行开始(必须方在文件的第一行): #!/bin/sh 符号#!用来 ...
- 磁盘性能,你可能不知道的IOPS计算方法
每个I/O 请求到磁盘都需要若干时间.主要是因为磁盘的盘边必须旋转,机头必须寻道.磁盘的旋转常常被称为”rotational delay”(RD),机头的移动称为”disk seek”(DS).一个I ...
- Android 开发笔记 “Sqlite Cursor 使用”
使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...
- iter, yield与enumerate的实现
模拟实现一个enumerate函数 def myEnumerate(seq, start=0): results = [] n = start for i in seq: results.append ...