归并排序详解(python实现)
因为上个星期leetcode的一道题(Median of Two Sorted Arrays)所以想仔细了解一下归并排序的实现。
还是先阐述一下排序思路:
首先归并排序使用了二分法,归根到底的思想还是分而治之。拿到一个长数组,将其不停的分为左边和右边两份,然后以此递归分下去。然后再将她们按照两个有序数组的样子合并起来。这样说起来可能很难理解,于是给出一张我画的图。

这里显示了归并排序的第一步,将数组按照middle进行递归拆分,最后分到最细之后再将其使用对两个有序数组进行排序的方法对其进行排序。
两个有序数组排序的方法则非常简单,同时对两个数组的第一个位置进行比大小,将小的放入一个空数组,然后被放入空数组的那个位置的指针往后 移一个,然后继续和另外一个数组的上一个位置进行比较,以此类推。到最后任何一个数组先出栈完,就将另外i一个数组里的所有元素追加到新数组后面。
由于递归拆分的时间复杂度是logN 然而,进行两个有序数组排序的方法复杂度是N该算法的时间复杂度是N*logN 所以是NlogN。
根据这波分析,我们可以看看对上图的一个行为。
当最左边的分到最细之后无法再划分左右然后开始进行合并。
第一次组合完成[4, 7]的合并
第二次组合完成[4, 7, 8]的合并
第三次组合完成[3, 5]的合并
第四次组合完成[3, 5, 9]的合并
第五次组合完成[3, 4, 5, 7, 8, 9]的合并结束排序。
下面放上python的代码
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1 if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i) return c def merge_sort(lists):
if len(lists) <= 1:
return lists
middle = len(lists)/2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right) if __name__ == '__main__':
a = [4, 7, 8, 3, 5, 9]
print merge_sort(a)
Java 实现
package com.geektime.SortQ; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class MergeSort { public void merge(List<Integer> arrays, List<Integer> pp, List<Integer> gg, int start, int end) {
int pIndex = 0;
int gIndex = 0;
ArrayList<Integer> temp = new ArrayList<Integer>();
while (true) {
if (pp.get(pIndex) >= gg.get(gIndex)) {
temp.add(gg.get(gIndex));
gIndex++;
} else {
temp.add(pp.get(pIndex));
pIndex++;
}
if (gIndex == gg.size()) {
for (int i = pIndex; i < pp.size(); i++)
temp.add(pp.get(i));
break;
} else if (pIndex == pp.size()) {
for (int j = gIndex; j < gg.size(); j++)
temp.add(gg.get(j));
break;
}
} for (int op = 0; op < temp.size(); op++) {
arrays.set(start+op, temp.get(op));
}
} public void mergeSort(ArrayList<Integer> arrays, int start, int end) {
if (start >= end)
return;
int mid = (start + end) / 2; mergeSort(arrays, start, mid);
mergeSort(arrays, mid+1, end);
List<Integer> pp = arrays.subList(start, mid+1);
List<Integer> gg = arrays.subList(mid+1, end+1);
merge(arrays, pp, gg, start, end);
} public static void main(String[] args) {
MergeSort bb = new MergeSort();
ArrayList<Integer> arrayList = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 3, 2, 1));
bb.mergeSort(arrayList,0, 5);
System.out.println(arrayList);
}
}
归并排序详解(python实现)的更多相关文章
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
- 详解Python模块导入方法
python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...
- 详解python函数的参数
详解python函数的参数 一.参数的定义 1.函数的参数在哪里定义 在python中定义函数的时候,函数名后面的括号里就是用来定义参数的,如果有多个参数的话,那么参数之间直接用逗号, 隔开 案列: ...
- 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类 Python中函数参数定义及调用函数时传参 ...
- 详解Python 切片语法
Python的切片是特别常用的功能,主要用于对列表的元素取值.这篇文章主要介绍了详解Python 切片语法,需要的朋友可以参考下 Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片 ...
- 详解Python编程中基本的数学计算使用
详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...
- 详解Python中内置的NotImplemented类型的用法
它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...
- 详解python的装饰器decorator
装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...
随机推荐
- DamonOehlman/detect-browser
https://github.com/DamonOehlman/detect-browser detect-browser This is a package that attempts to det ...
- wallet.metamask.io 网页版钱包 connecting unknown network导致页面卡住
之前在还不是十分懂用的时候想要用其连接本地的打开的ganache,所以就像使用本地插件的metamask一样,点击custom rpc,然后输入http://localhost:7545,然后页面就一 ...
- leetcode701. Insert into a Binary Search Tree
https://www.cnblogs.com/grandyang/p/9914546.html 类似于二分查找的方法,用迭代的方法去做 注意:无论是进入左子树还是右子树,左右子树都变成了新的数,所以 ...
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree 236. Lowest Common Ancestor of a Binary Tree
https://www.cnblogs.com/grandyang/p/4641968.html http://www.cnblogs.com/grandyang/p/4640572.html 利用二 ...
- QT listwiget 控件添加图片
很多的时候我们需要制作类似手机的中的电子相框, 可以用listwidget 控件实现 直接上代码 MainWindow::MainWindow(QWidget *parent) : QMainWind ...
- Selenium:三种等待方式
UI自动化测试,大多都是通过定位页面元素来模拟实际的生产场景操作.但在编写自动化测试脚本中,经常出现元素定位不到的情况,究其原因,无非两种情况:1.有frame:2.没有设置等待. 因为代码运行速度和 ...
- JDK 升级问题小结
JDK8 发布很久了,它提供了许多吸引人的新特性,能够提高编程效率. 如果是新的项目,使用 JDK8 当然是最好的选择.但是,对于一些老的项目,升级到 JDK8 则存在一些兼容性问题,是否升级需要酌情 ...
- thymeleaf参考手册
1.创建 html <!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"></html&g ...
- PV和并发、以及计算web服务器的数量的方法
几个概念 网站流量是指网站的访问量,用来描述访问网站的用户数量以及用户所浏览的网页数量等指标,常用的统计指标包括网站的独立用户数量.总用户数量(含重复访问者).网页浏览数量.每个用户的页面浏览数量.用 ...
- Qt Creator 中,如何更改h,cpp,ui的文件并不让ui失效
这个星期在使用qt,碰到一个很蛋疼的问题:创建对话框的时候,不小心输错了名字.而且是在很迟才发现的.这个时候对话框都已经布局差不多了,为了改名字,碰到更蛋疼的问题,改了名字后就无法使用转到槽的功能了. ...