Java与算法之(11) - 合并排序
天下事,合久必分,分久必合。合并排序的基本思想正是先分再合。
例如对3, 1这个数列排序,首先是分,分为3和1两个数列,然后再合并并排序。合并需要额外的辅助空间,即建立一个两个数列长度之和的空数组用于存储合并结果。
合并分为三步:
1)两个数列在起始位置各分配一个"指针",对比指针位置的数字,取较小的数字存入辅助数组。数字被移出的一侧,指针右移一格,再次比较两个指针位置的数字,直到某一侧的指针移出数组以外结束。
2)把左侧数组剩余的数字按顺序移动到辅助数组中
3)把右侧数组剩余的数字按顺序移动到辅助数组中
过程如下图:
下面把两个数组的长度都增加到2,再看一下合并过程:
观察一下这个流程可以看出,这种合并排序的前提是左右两个数列本身是有序的。所以如果对4, 2, 3, 1排序,拆成4, 2和3, 1两个数列显然是不行的,需要继续拆分4, 2为4和2,然后合并为2, 4;拆分右侧为3, 1,然后合并成1, 3。最后合并2, 4和1, 3。
以4, 3, 6, 2, 7, 1, 5为例,完整的排序过程如下图:
来看代码:
- import java.util.Arrays;
- /**
- * 合并排序法
- * Created by autfish on 2016/9/20.
- */
- public class MergeSort {
- public static void main(String[] args) {
- int[] numbers = new int[] {4, 3, 6, 2, 7, 1, 5};
- System.out.println("排序前: " + Arrays.toString(numbers));
- MergeSort ms = new MergeSort();
- ms.sort(numbers, 0, numbers.length - 1);
- System.out.println("排序后: " + Arrays.toString(numbers));
- }
- public void sort(int[] numbers, int from, int to) {
- int middle = (from + to) / 2;
- if (from < to) {
- sort(numbers, from, middle);
- sort(numbers, middle + 1, to);
- //左侧数列最大值小于右侧数列最小值, 不需要通过合并来调整顺序
- if(numbers[middle] < numbers[middle + 1])
- return;
- merge(numbers, from, middle, to);
- }
- }
- private void merge(int[] numbers, int from, int middle, int to) {
- int[] temp = new int[to - from + 1];
- int left = from;
- int right = middle + 1;
- int i = 0;
- //从拆分到两边数列各剩一个数字开始合并; 当数列中有多个数字时, 一定是已经排好序的
- //从两边数列左侧开始依次取数对比, 挑选小的一个放入临时数组
- while (left <= middle && right <= to) {
- if (numbers[left] < numbers[right]) {
- temp[i++] = numbers[left++];
- } else {
- temp[i++] = numbers[right++];
- }
- }
- //把左边数列剩余的数移入数组
- while (left <= middle) {
- temp[i++] = numbers[left++];
- }
- //把右边数列剩余的数移入数组
- while (right <= to) {
- temp[i++] = numbers[right++];
- }
- System.arraycopy(temp, 0, numbers, from, temp.length);
- }
- }
运行:
- 排序前: [4, 3, 6, 2, 7, 1, 5]
- 排序后: [1, 2, 3, 4, 5, 6, 7]
合并排序平均情况和最坏情况的时间复杂度都是O(nlogn),因为需要额外的辅助空间,空间复杂度为O(n)。
Java与算法之(11) - 合并排序的更多相关文章
- 算法笔记_014:合并排序(Java)
1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...
- Java与算法之(10) - 希尔排序
希尔排序是插入排序的一种,是直接插入排序的改进版本. 对于上节介绍的直接插入排序法,如果数据原来就已经按要求的顺序排列,则在排序过程中不需要进行数据移动操作,即可得到有序数列.但是,如果最初的数据是按 ...
- c++(合并排序)
前面一篇博客提到的快速排序是排序算法中的一种经典算法.和快速排序一样,合并排序是另外一种经常使用的排序算法.那么合并排序算法有什么不同呢?关键之处就体现在这个合并上面. 合并算法的基本步骤如下所 ...
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. ...
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...
- Shell排序算法和合并排序算法
Shell排序(希尔排序)算法Shell排序严格来说基于插入排序的思想,其又称为希尔排序或者缩小增量排序. Shell排序的流程:1.将由n个元素的数组分成n/2个数字序列,第1个数据和第n/2+1个 ...
- java讲讲几种常见的排序算法(二)
java讲讲几种常见的排序算法(二) 目录 java讲讲几种常见的排序算法(一) java讲讲几种常见的排序算法(二) 堆排序 思路:构建一个小顶堆,小顶堆就是棵二叉树,他的左右孩子均大于他的根节点( ...
- 用 Java 实现的八种常用排序算法
八种排序算法可以按照如图分类 交换排序 所谓交换,就是序列中任意两个元素进行比较,根据比较结果来交换各自在序列中的位置,以此达到排序的目的. 1. 冒泡排序 冒泡排序是一种简单的交换排序算法,以升序排 ...
- 数据结构和算法 – 11.高级排序算法(上)
对现实中的排序问题,算法有七把利剑可以助你马道成功. 首先排序分为四种: 交换排序: 包括冒泡排序,快速排序. 选择排序: 包括直接选择排序,堆排序. 插入排序 ...
随机推荐
- Photoshop 无法打开某些JPEG文件的成因
最近想把QQ相册里的一些照片整理修复一下,所以下载了一些到本地,然后用PS CC 2018打开,结果PS告诉我"无法完成请求,因为程序错误".试了Win10系统自带的看图软件,能够 ...
- VM虚拟机连Linux黑屏问题
在尝试了关闭VM的加速3D图形后,若仍黑屏(但是挂起时却能显示),可以尝试在以管理员身份cmd中输入netsh winsock reset,重启后可以恢复正常.这个问题似乎与网络某个端口有关,我上次打 ...
- Mybatis-----优化配置文件,基于注解CR
这篇主要写配置文件的优化,例如 jdbc.properties 配置文件 ,引入数据库的文件,例如driver,url,username,password 等,然后在 SqlMapConfig.x ...
- ADODB.Connection、ADODB.RecordSet
1.数据库连接对象(ADODB. Connection)该对象用于与ODBC数据库建立连接,所有对数据库的操作均通过该连接进行.数据库连接对象ADODB. Connection的作用象Delphi中的 ...
- 贪心算法——Fence Repair(POJ 3253)
题目描述 农夫约翰为了修理栅栏,要将一块很长的木板切割成N块.准备切成的木板长度为L1,L2,L3--LN,未切割前木板的长度恰好为切割后木板长度的总和.每次切断木板时,需要的开销为这块木板的长度.请 ...
- python 将文件夹内的图片转换成PDF
import os import stringfrom PIL import Imagefrom reportlab.lib.pagesizes import A4, landscapefrom re ...
- bzoj 4012: [HNOI2015]开店 主席树
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- Java-单例模式详解(图文并茂,简单易懂)
PS:首先我们要先知道什么是单例,为什么要用单例,用的好处是什么等问题来看. 1:java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例单例模式有以下 ...
- DBA之路
对于一个励志要成为DBA的人,虽然还有不足,梦想还是要有的,万一实现了呢.做一个关于DBA成长之路的相关目录,作为灯塔. --------------------------------------- ...
- 快速恢复开发环境(系统还原后的思考,附上eclipse注释的xml配置文件)
1.Eclipse/Myeclipse的工作空间,不能放在系统盘 除非你的项目都有实时的云同步或SVN等,才能放在系统固态盘,不然你享受快速启动项目的同时,也需要承担系统奔溃后找不回项目的风险: 公司 ...