java 数据合并算法_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
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) - 合并排序相关推荐
- java常见的算法_Java常用算法总结(转)
交换排序 冒泡排序 将最后一个元素与倒数第二个元素对比,如果最后一个元素比倒数第二个小,则交换两个元素的位置,再用倒数第二个元素与倒数第三个元数对比,直到比到第一个元素,这样经过第一趟排序后得到第一个 ...
- java g1 详解_JAVA垃圾收集算法总结以及CMS、G1算法详解
前段时间由于工作原因一直很忙,上周项目验收后时间终于空闲下来,博客也有好几个月没有更新了,趁着还有几天放假,借这个机会写点东西:网上也有很多人写过Java垃圾收集器,特别现在主流比较火的CMS和G1算 ...
- java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...
本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...
- java求公式例题_JAVA经典算法40题
1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...
- java经典50题_JAVA经典算法50题(3)【面试+工作】
原标题:JAVA经典算法50题(3)[面试+工作] JAVA经典算法50题(3)[面试+工作] [程序21] 题目:求1+2!+3!+...+20!的和. 1.程序分析:此程序只是把累加变成了累乘. ...
- linux公社 java算法_Java快速排序算法
快速排序算法思想: 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一 ...
- java程序两点之间最短路径算法_java 最短路径算法 如何实现有向 任意两点的最短路径...
展开全部 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节e68a8462616964757a686964616f31333361316131点的最短路径.主要 ...
- java 抽奖算法_Java抽奖算法第二例
本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下 1. 算法分析 根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品. 2. 代码核心算法 ...
- java 常用算法_Java常见算法整理
兔子问题(斐波那契数列规律) 台阶问题 (兔子问题变种,递归规律) 素数问题(判断素数.质数方式) 水仙花数问题(数字分解) 查找算法(二分查找) 排序算法(选择排序,冒泡排序,快速排序) 兔子问题, ...
最新文章
- Neutron 物理部署方案 - 每天5分钟玩转 OpenStack(68)
- android进度条课设报告,Android开发之进度条ProgressBar的示例代码
- 学习笔记101— word 如何给某一页后面所有页增加行号
- L8.1 lvs+heartbeat-ldirectord实现高可用负载均衡
- 大数据简介,技术体系分类整理
- 关于如果减少勒索病毒的侵扰:
- Unity插件——Odin 学习笔记(三)
- 前端车牌识别SDK算法及原理
- DeBUG|实例化servlet类xxxx异常
- java判断闰年的方法_Java判断闰年的2种方法示例|chu
- Spring Cloud的注册中心和服务者,消费者的构建
- 婚礼筹备之WBS工作分解结构(转)
- Asterisk内核 拾遗
- java游戏源码合集,已整理成文档
- UI设计中最重要的元素和原则是什么
- 104 polkadot substrate : 许可网络
- 乔布斯在斯坦福大学的演讲感悟
- java企业网站源码 后台springmvc SSM 前台静态引擎 代码生成器
- 关于发射功率与增益问题
- 微信服务器向公众号推送消息或事件后,开发者5秒内没有返回