基础排序算法之并归排序(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) ...
随机推荐
- pom.xml中<dependency>
当想下载jar包时,需要在pom.xml追加<dependency>即可. 通过如下餐叙: 如下图 http://mvnrepository.com/artifact/cglib/cgli ...
- XMPPFramework ios 例子中链接服务器失败,opnefire 服务器链接失败
首先说下上周又做了几天得无用功, 之前一直用的是ejabberd ,这次换了opnefire,有人说opnefire跟新的xmpp协议不兼容,后来又更换成了ejabberd, Github 上得dem ...
- Python:模块引用
#!/usr/bin/python3 #Filename function.py #导入模块 import sys #导入function.py#function.py 文件import functi ...
- Constructor and destructor -- Initialization & Cleanup in C++
Why need initialization and cleanup? A large segment of C bugs occur when the programmer forgets to ...
- java设计模式——接口模式
java将接口的概念提升为独立的结构,体现了接口与实现分离.java接口允许多个类提供相同的功能,也允许一个同时实现多个接口.java的接口与抽象类十分相似.java与抽象类中的区别: 1.一个类可以 ...
- php批量发送短信或邮件的方案
最近遇到在开发中遇到一个场景,后台管理员批量审核用户时候,需要给用户发送审核通过信息,有人可能会想到用foreach循环发送,一般的短信接口都有调用频率,循环发送,肯定会导致部分信息发送失败,有人说用 ...
- 如何便携使用github
Git是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.目前,包括Rubinius ...
- 运用预加载提升H5移动页面的用户体验
原文地址:http://www.grycheng.com/?p=2188 在做h5移动页面,相信大家一定碰到过页面已经打开,但是里面的图片还未加载出来的情况,这种问题虽然不影响页面的功能,但是不利于用 ...
- In Place Upgrade of CentOS 6 to CentOS 7
Note: This is not the most highly recommended method to move from CentOS 6 to CentOS 7 ... but it ca ...
- 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader
20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...