归并排序的原理及java代码实现
作者:hebedich 发布时间:2021-11-18 13:51:10
标签:java归并排序
概述
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
归并排序采用的是递归来实现,属于“分而治之”,将目标数组从中间一分为二,之后分别对这两个数组进行排序,排序完毕之后再将排好序的两个数组“归并”到一起,归并排序最重要的也就是这个“归并”的过程,归并的过程中需要额外的跟需要归并的两个数组长度一致的空间。
效果图:
步骤
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
实例
原始数据:
3 5 2 6 2
归并的前提是将数组分开,一分为二,再一分为二,分到不能再分,进行归并。
第一轮分隔,索引2 ((0+4)/2=2) 为中间
[3 5 2] [6 2]
第二轮分隔,对[3 5 2]进行分隔
[3 5] [2] [6 2]
第三轮分隔,对[3 5]进行分隔
[3] [5] [2] [6 2]
合并[3] [5]
[3 5] [2] [6 2]
合并[3 5] [2]
[2 3 5] [6 2]
第四轮分隔,对[6 2]进行分隔
[2 3 5] [6] [2]
合并[6] [2]
[2 3 5] [2 6]
合并[2 3 5] [2 6]
[2 2 3 5 6]
代码实现(Java)
package com.coder4j.main.arithmetic.sorting;
public class Merge {
private static int mark = 0;
/**
* 归并排序
*
* @param array
* @param low
* @param high
* @return
*/
private static int[] sort(int[] array, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
mark++;
System.out.println("正在进行第" + mark + "次分隔,得到");
System.out.println("[" + low + "-" + mid + "] [" + (mid + 1) + "-" + high + "]");
// 左边数组
sort(array, low, mid);
// 右边数组
sort(array, mid + 1, high);
// 左右归并
merge(array, low, mid, high);
}
return array;
}
/**
* 对数组进行归并
*
* @param array
* @param low
* @param mid
* @param high
*/
private static void merge(int[] array, int low, int mid, int high) {
System.out.println("合并:[" + low + "-" + mid + "] 和 [" + (mid + 1) + "-" + high + "]");
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (array[i] < array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
// 两个数组之一可能存在剩余的元素
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = array[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = array[j++];
}
// 把新数组中的数覆盖array数组
for (int m = 0; m < temp.length; m++) {
array[m + low] = temp[m];
}
}
/**
* 归并排序
*
* @param array
* @return
*/
public static int[] sort(int[] array) {
return sort(array, 0, array.length - 1);
}
public static void main(String[] args) {
int[] array = { 3, 5, 2, 6, 2 };
int[] sorted = sort(array);
System.out.println("最终结果");
for (int i : sorted) {
System.out.print(i + " ");
}
}
}
测试输出结果:
正在进行第1次分隔,得到
[0-2] [3-4]
正在进行第2次分隔,得到
[0-1] [2-2]
正在进行第3次分隔,得到
[0-0] [1-1]
合并:[0-0] 和 [1-1]
合并:[0-1] 和 [2-2]
正在进行第4次分隔,得到
[3-3] [4-4]
合并:[3-3] 和 [4-4]
合并:[0-2] 和 [3-4]
最终结果
2 2 3 5 6
经测试,与实例中结果一致。


猜你喜欢
- 本文实例为大家分享了Android实现手机自动获取短信验证码功能,供大家参考,具体内容如下1、短信监听广播2、读取短信内容3、截取短信内容【
- using System; using System.IO; namespace DelAllLrcFiles { class Progra
- —学习并使用mybatis-plus的一些高级功能的用法例如: AR模式、 乐观锁 、逻辑删除 、自动填充、数据保护等功能为了方便演示,咱们
- 本文实例为大家分享了Intent实现页面跳转的两种的方法,供大家参考,具体内容如下下图中两个不同的方法就是两种页面之间跳转的情况1).跳转不
- 请求映射源码首先看一张请求完整流转图(这里感谢博客园上这位大神的图,博客地址我忘记了):前台发送给后台的访问请求是如何找到对应的控制器映射并
- 1、任何的高并发,请求总是会有一个顺序的2、java的队列的数据结构是先进先出的取值顺序3、BlockingQueue类(线程安全)(使用方
- MongoDB的基本使用添加依赖<dependency>
- 1 ArrayList在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:说明:ArrayList实现了Ra
- 本文实例讲述了C#动态调用事件的方法。一般来说,传统的思路是,通过Reflection.EventInfo获得事件的信息,然后使用GetRa
- 本文实例为大家分享了Android自定义圆环倒计时控件的具体代码,供大家参考,具体内容如下先来一张最终效果图:主要思路: 在画渐变
- 一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如第6页用6表示而不是06或0
- 本文实例为大家分享了ActionBar下拉式导航的实现代码,供大家参考,具体内容如下利用Actionbar同样可以很轻松的实现下拉式的导航方
- spring boot版本和spring cloud版本框架版本SpringBoot2.3.12.RELEASESpringCloudHox
- 本文实例为大家分享了Android实现截长图功能的具体代码,供大家参考,具体内容如下先看看手机自带的长截屏功能: 机型: viv
- 本文实例讲述了Jaxb2实现JavaBean与xml互转的方法。分享给大家供大家参考,具体如下:一、简介JAXB(Java Architec
- Navigation 组件支持 Jetpack Compose 应用。我们可以在利用 Navigation 组件的基础架构和功能,在可组合项
- 写在前面Linux:CentOS7.5Spark: spark-3.0.0-bin-hadoop3.2IDE:IntelliJ IDEA20
- 基于比较的排序算法基本原理及Java实现1. 七大基于比较的排序-总览1.1常见基于比较的排序分类1.2时间复杂度,空间复杂度以及稳定性。稳
- 注解类@Documented@Target({ElementType.METHOD})@Retention(RetentionPolicy.
- 先来看看效果图跳动的小球做这个动画,需掌握: 1、属性动画