基础排序算法之并归排序(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) ...
随机推荐
- Could not parse mapping document from resource cn/spt/model/Student.hbm.xml
初始hibernate, 写第一个程序 helloworld的错误: Exception in thread "main" org.hibernate.InvalidMapping ...
- Winedt 7.0 Build: 20120321 永久试用方法 WinEdt 7.0 破解
该方法,不是破解. 因为WinEdt试用版与正式版功能无异. 所以,该方法是 通过更新注册表信息,重置安装时间. 也就是重新获取31天的试用期时长. 方法如下: 1.用管理员权限打开CMD. 2.运行 ...
- JS 定時刷新父類頁面
function timeCount() { var url = "MAC.aspx"; parent.location.href = url; } function beginC ...
- Linux Shell编程学习笔记——目录(附笔记资源下载)
LinuxShell编程学习笔记目录附笔记资源下载 目录(?)[-] 写在前面 第一部分 Shell基础编程 第二部分 Linux Shell高级编程技巧 资源下载 写在前面 最近花了些时间学习She ...
- 枚举N行N列的自然数列
数据库环境:SQL SERVER 2005 现有一个需求,要枚举1-50个自然数,分10行5列展示.如图,
- Gulp那些好用的插件 2016.04.20
开始接触LESS.组件化编程后,慢慢意识到需要一个提高工作效率的构建工具,就此接触到了Gulp. Gulp的好处在这里就不细说啦,只有四个API接口学起来简直爽歪歪,减少了大量的I/O操作,用起来很畅 ...
- ASP.NET中扩展FileUpload的上传文件的容量
ASP.NET中扩展FileUpload只能上传小的文件,大小在4MB以内的.如果是上传大一点的图片类的可以在web.config里面扩展一下大小,代码如下 <system.web> &l ...
- C语言变量声明加冒号的用法
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...
- 初识EL表达式
1.EL最初出现在JSTL,后来引入JSP 2.核心作用:减少JSp中Java代码数量,同时方便修改 3.算术.逻辑.关系符号都是两种,防止出现歧义,比如:/和div,%和mod,>=和ge,相 ...
- 自己写的carousel
可以 function appendRight() { //alert("right"); lastItem = itemsRight[urls.length - ]; first ...