基础排序算法之并归排序(Merge Sort)
并归排序是学习分治法 (Merge Sort) 的好例子。而且它相对于选择,插入,冒泡排序来说,算法性能有一定提升。我首先会描述要解决的问题,并给出一个并归排序的例子。之后是算法的思路以及给出伪代码。算法的实现部分用Python完成。最后自己尝试说明白算法分析。
问题描述
问题描述很简单,输入一组未排序的数组,如左边的数组,通过并归排序算法的计算,输出一组正确排序的数组,如右边的数组。

如果利用上面这个例子来做并归排序的话,应该首先将该数组切割成两半,对左边一半进行排序,在对右边一半进行排序,在合并排序好的左右数组。如下图所示:

思路和伪代码
可以从例子中看出,并归排序就是一个先分后合的过程:
- 递归排序左半部分数组;
- 递归排序右半部分数组;
- 合并 (Merge) 这两部分生成最后结果。
合并 (Merge)过程的核心思想就是:给左右两个数组分别设定一个标记符号i和j,通过比对当前i和j位置的数的大小,选择小的值加入到最后的结果中去。
合并(Merge) 的伪代码:
C = output[length=n]
A = 1st sorted array[n/2]
B = 2st sorted array[n/2]
i = 1
j = 1
for k=1 to n
if A(i) < B(j)
C(k) = A(i)
i++
else B(j) < A(i)
C(k) = B(j)
j++
end
算法实现
def merge(left, right):
result = []
i, j=0, 0
ll, lr = len(left), len(right)
while i < ll and j < lr:
if i < ll and j < lr:
if left[i] < right[j]:
result.append(left[i])
i = i+1
else:
result.append(right[j])
j =j+1
result+=left[i:]
result+=right[j:]
return result def merge_sort(datalist):
length=len(datalist)
result=datalist
if length>1:
left=datalist[0:int(length/2)]
right=datalist[int(length/2):length]
left=merge_sort(left)
right=merge_sort(right)
result=merge(left,right)
return result
算法分析
首先来分析在合并 (Merge) 过程的所需要的运行时间。
C = output[length=n]
A = 1st sorted array[n/2]
B = 2st sorted array[n/2]
i = 1
j = 1
for k=1 to n
if A(i) < B(j)
C(k) = A(i)
i++
else B(j) < A(i)
C(k) = B(j)
j++
end
第4和5行分别需要一次操作,整个for循环中,一次循环需要四次操作,假如有m个数那么for循环整个需要4m次操作,那么最后的运行时间为4m+2。因为m总是大于1,所以为了方便计算,假设最后运行时间小于6m。
之后再来看整个算法的运行时间,采用递归树的方法,树的高度为lgn+1,树的每一层运行时间都是6n,总共的运行时间为6nlgn+6n。所以合并排序的时间复杂度为O(nlgn)。
基础排序算法之并归排序(Merge Sort)的更多相关文章
- Java常见排序算法之直接选择排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- Java排序算法之直接选择排序
Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...
- 常见的排序算法(直接插入&选择排序&二分查找排序)
1.直接插入排序算法 源码: package com.DiYiZhang;/* 插入排序算法 * 如下进行的是插入,排序算法*/ public class InsertionSort { pub ...
- 八大排序算法之二希尔排序(Shell Sort)
希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进.希尔排序又叫缩小增量排序 基本思想: 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 ...
- Java排序算法(四):Shell排序
[基本的想法] 将原本有大量记录数的记录进行分组.切割成若干个子序列,此时每一个子序列待排序的记录个数就比較少了,然后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时.再对全体记录进行一次直 ...
- PHP算法之排序算法(PHP内置排序函数)
首先用实例来讲述一下PHP内置的一些排序函数 [a / k] sort [/ rsort]:[保留索引关系 / 按键名(保留键名关系,适用于关联数组)] 对数组进行排序,结束时数组单元将被从最低到最高 ...
- C语言中的排序算法--冒泡排序,选择排序,希尔排序
冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...
- 几种排序算法及Java实现排序的几种方式
几种排序算法 下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序 package date201709.date20170915; public class SortUtil ...
- 排序算法七:基数排序(Radix sort)
上一篇提到了计数排序,它在输入序列元素的取值范围较小时,表现不俗.但是,现实生活中不总是满足这个条件,比如最大整形数据可以达到231-1,这样就存在2个问题: 1)因为m的值很大,不再满足m=O(n) ...
随机推荐
- 8第八章CTE递归及分组汇总高级部分(多维数据集)(转载)
8第八章CTE递归及分组汇总高级部分(多维数据集) 这里贴图太麻烦...算了 UNION 等集合操作符: UNION 等以第一个 SELECT 的 列明 作为 整个结果集的列明,整个结果集 唯一认可 ...
- 适合自己的vim配置文件
主要用来写c++的:clang-completer这个是单独安装的,其他的都采用的vundle安装完成. clang-completer:只在centos7.2上安装成功过,6.4上失败了.先要安装一 ...
- 如何禁用easyui-linkbutton 中的Click事件
eg: <a id="btn" href="#" class="easyui-linkbutton" data-options=&qu ...
- ExecuteReader
最近在做winform的编程,想到一真没有使用过ExecuteReader.可能以前以后它的用户不大,或者 不大好用,故没有用过.今天在这里将学习记录写下来,供读者参考: 1.MSDN上说:Sends ...
- python基础之列表常用操作及知识点小结
列表(list) List(列表) 是 Python 中使用最频繁的数据类型.列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(所谓嵌套).列表用[ ]标识,是pyth ...
- 初级SQL开发汇总指南
汇总部分内容来自网络(作者 :zhtbs),比较基础的东西,能够了解比较基础的一些东西. Select语句概要 数据库中数据的提取(查询)使用select 语法,主要有以下几点作用 l 提取的数据 ...
- C# mvc 验证码3
//// <summary> /// 生成验证码 /// </summary> /// <param name="length">指定验证码的长 ...
- 控制反转(IoC)与依赖注入(DI)
1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接 ...
- Linq 数据合并,比较,连接,交叉 维恩图工具
Except 返回包含两个不同之处的linq结果集 Intersect 返回两个容器中共同的数据项 Union 返回所有成员,相同的成员出现多次,将只返回一个 Concat 返回所有数据项
- bzoj 1486: [HNOI2009]最小圈 dfs求负环
1486: [HNOI2009]最小圈 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1022 Solved: 487[Submit][Status] ...