天下事,合久必分,分久必合。合并排序的基本思想正是先分再合。

例如对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

sort(numbers, from, middle);

sort(numbers, middle + 1, to);

//左侧数列最大值小于右侧数列最小值, 不需要通过合并来调整顺序

if(numbers[middle]

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]

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 数据合并算法_Java与算法之(11) - 合并排序相关推荐

  1. java常见的算法_Java常用算法总结(转)

    交换排序 冒泡排序 将最后一个元素与倒数第二个元素对比,如果最后一个元素比倒数第二个小,则交换两个元素的位置,再用倒数第二个元素与倒数第三个元数对比,直到比到第一个元素,这样经过第一趟排序后得到第一个 ...

  2. java g1 详解_JAVA垃圾收集算法总结以及CMS、G1算法详解

    前段时间由于工作原因一直很忙,上周项目验收后时间终于空闲下来,博客也有好几个月没有更新了,趁着还有几天放假,借这个机会写点东西:网上也有很多人写过Java垃圾收集器,特别现在主流比较火的CMS和G1算 ...

  3. java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...

    本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...

  4. java求公式例题_JAVA经典算法40题

    1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...

  5. java经典50题_JAVA经典算法50题(3)【面试+工作】

    原标题:JAVA经典算法50题(3)[面试+工作] JAVA经典算法50题(3)[面试+工作] [程序21] 题目:求1+2!+3!+...+20!的和. 1.程序分析:此程序只是把累加变成了累乘. ...

  6. linux公社 java算法_Java快速排序算法

    快速排序算法思想: 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一 ...

  7. java程序两点之间最短路径算法_java 最短路径算法 如何实现有向 任意两点的最短路径...

    展开全部 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节e68a8462616964757a686964616f31333361316131点的最短路径.主要 ...

  8. java 抽奖算法_Java抽奖算法第二例

    本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下 1. 算法分析 根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品. 2. 代码核心算法 ...

  9. java 常用算法_Java常见算法整理

    兔子问题(斐波那契数列规律) 台阶问题 (兔子问题变种,递归规律) 素数问题(判断素数.质数方式) 水仙花数问题(数字分解) 查找算法(二分查找) 排序算法(选择排序,冒泡排序,快速排序) 兔子问题, ...

最新文章

  1. Neutron 物理部署方案 - 每天5分钟玩转 OpenStack(68)
  2. android进度条课设报告,Android开发之进度条ProgressBar的示例代码
  3. 学习笔记101— word 如何给某一页后面所有页增加行号
  4. L8.1 lvs+heartbeat-ldirectord实现高可用负载均衡
  5. 大数据简介,技术体系分类整理
  6. 关于如果减少勒索病毒的侵扰:
  7. Unity插件——Odin 学习笔记(三)
  8. 前端车牌识别SDK算法及原理
  9. DeBUG|实例化servlet类xxxx异常
  10. java判断闰年的方法_Java判断闰年的2种方法示例|chu
  11. Spring Cloud的注册中心和服务者,消费者的构建
  12. 婚礼筹备之WBS工作分解结构(转)
  13. Asterisk内核 拾遗
  14. java游戏源码合集,已整理成文档
  15. UI设计中最重要的元素和原则是什么
  16. 104 polkadot substrate : 许可网络
  17. 乔布斯在斯坦福大学的演讲感悟
  18. java企业网站源码 后台springmvc SSM 前台静态引擎 代码生成器
  19. 关于发射功率与增益问题
  20. 微信服务器向公众号推送消息或事件后,开发者5秒内没有返回

热门文章

  1. 解决Windows对JDK默认版本切换问题
  2. 关于ubuntu系统无线网络网速慢的解决方法
  3. 什么是按位移位(位移)运算符以及它们如何工作?
  4. 机器人操作系统来到Windows
  5. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
  6. linux线程的实现【转】
  7. DataTable.DataRow的复制
  8. bootstrap搜索框样式代码及效果
  9. Azure正式对外发布容器服务,支持Swarm和Mesos
  10. 不用Office自动化技术,给Word文档中填充赋值