选择排序的升级版本归并排序, 归并排序有二路归并,三路归并和多路归并,我这次只分析下二路归并,有机会在分析下别的。

归并排序的思想是这样的:

设数组a中存放了n个数据元素,初始时我们把它们看成是n个长度为1的有序子数组,然后从第一个子数组开始,把相临的子数组两两合并,得到n/2个(若n/2为小数则上取整)长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1);对这些新的有序子数组再两两归并;如此重复,直到得到一个长度为n的有序数组为止。多于二路的归并排序方法和二路归并排序方法类同。

步骤:

1、首先是将数组分开, 应用递归的方式, 简单暴力;

2、然后对数组进行两辆归并(就是合并为一个数组的过程);

3、第二步的过程中需要创建一个新的数组,对改变顺序后的原数组的部分进行保存;‘

//也许代码是说明问题的最好方法, 代码中已经做了注释

package merge;

public class MergeSort {
// 接收传来的参数 对数组进行拆分
public int[] sort(int[] array, int low, int high) {
if (low < high) {
int middle = (low + high) / 2;
sort(array, low, middle);
sort(array, middle + 1, high);
// 进行排序和合并
merge(array, low, middle, high);
}
return array;
} // 进行排序和合并
public void merge(int[] array, int low, int middle, int high) {
// 创建一个临时数组
int cLow = low;
int[] tempArray = new int[array.length];
// 定义临时数组及参数数组下标如下:
int tempIndex = low;
int right = middle + 1;
while(low <= middle && right <= high){
if(array[low] < array[right]){
tempArray[tempIndex++] = array[low++];
}else{
tempArray[tempIndex++] = array[right++];
}
} //如果条件满足的话,对middle前面的还没有存入的直接放入tempArray,因为middle后面的已经没有了
while(low <= middle){
tempArray[tempIndex++] = array[low++];
} //原理和上面的相同
while(right <= high){
tempArray[tempIndex++] = array[right++];
} //将排序后的 部分数组 重新放入原数组
for(int i = cLow; i <= high; i++){
array[i] = tempArray[i];
}
}
}

测试类如下:

package Test;

import merge.MergeSort;;

public class Test {
public static void main(String[] args) { MergeSort mergeSort = new MergeSort();
int[] array = createArray();
long ct1 = System.currentTimeMillis();
int[] arrays = mergeSort.sort(array, 0, array.length - 1);
long ct2 = System.currentTimeMillis();
display(arrays);
System.out.println("所消耗的时间:" + (ct2 - ct1) + " ms");
} public static void display(int[] arrays) {
System.out.println("排序后数据:");
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + "\t");
if ((i + 1) % 10 == 0) {
System.out.println();
}
}
System.out.println();
} public static int[] createArray() {
int[] array = new int[100000];
System.out.println("数组中元素是:");
for (int i = 0; i < 100000; i++) {
array[i] = (int) (Math.random() * 1000);
System.out.print(array[i] + "\t");
if ((i + 1) % 10 == 0) {
System.out.println();
}
} System.out.println();
return array;
}
}

归并排序对 100000个数进行排序的时间大约是  4300ms  , 可见比快排的效率低了很多。

时间复杂度的分析:

归并排序的总的时间复杂度为O(nlog2 n)。
归并排序需要的附加存储空间为O(n),所需辅助空间较大。
二路归并排序是稳定的。

归并排序(Java)的更多相关文章

  1. 归并排序 求逆序数 链表的归并排序 多线程归并排序 java

    import java.util.Scanner; public class Main { private static int count=0; public static void mergeso ...

  2. 二路归并排序java实现

    二路归并排序:其核心思想时将问题一分为二,并递归调用一分为二方法,使问题分割到不能再分各的原子问题,然后再归并,从实现原子问题开始,层层向上归并,最终解决整体问题.即所谓“分而治之,万流归一” 二路归 ...

  3. 自顶向下(递归)的归并排序和自底向上(循环)的归并排序——java实现

    归并排序有两种实现方式,自顶向下和自底向上.前者的思想是分治法,现将数组逐级二分再二分,分到最小的两个元素后,逐级往上归并,故其核心在于归并.后者的思想相反,采用循环的方式将小问题不断的壮大,最后变成 ...

  4. 单向链表的归并排序——java实现

    在做Coursera上的Algorithms第三周测验练习的时候有一道链表随机排序问题,刚开始没有什么思路,就想着先把单向链表归并排序实现了,再此基础上进行随机排序的改造.于是就结合归并排序算法,实现 ...

  5. 归并排序-java

    排序-归并排序 基本思想:是指将两个或两个以上的有序表合并成一个新的有序表. 具体步骤: (1首先将整个表看成是n个有序子表,每个子表的长度为1. (2)然后两两归并,得到n/2个长度为2的有序子表. ...

  6. leetcode23 多个拍好序的链表进行归并排序 (java版本)

    题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexit ...

  7. 归并排序java

    import java.util.Arrays; public class MergeSort { public static void main(String[] args) { MergeSort ...

  8. 归并排序—Java版

    一开始做算法的时候,感觉递归算法很绕,所以我就在阅读别人代码的基础上,对代码每一步都添加自己的注解,方便我以后的学习. public class MergeSort { /** * 归并排序 * @p ...

  9. 归并排序Java实现

    package practice; import edu.princeton.cs.algs4.*; /* * 归并排序 * 时间复杂度O(NlgN) N为数组长度 * 归并排序在小数组上表现并不好可 ...

  10. 归并排序——Java实现

    一.排序思想 将两个或两个以上的一排序文件合并成一个有序文件的过程叫归并,而归并排序就是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用.将以有序的了序列合并,得到完全有序 ...

随机推荐

  1. Delphi Screen.DataModuleCount 总是返回 0!Delphi 的 Bug? DataModuleCount = 0

         今天遇到一个很隐蔽的 Delphi 问题,不知做了什么,有一个功能总是不能使用,后来跟踪以下发现是因为 Screen.DataModuleCount 总是返回 0,而程序中一个函数正好要用到 ...

  2. poj_2104: K-th Number 【主席树】

    题目链接 学习了一下主席树,感觉具体算法思路不大好讲.. 大概是先建个空线段树,然后类似于递推,每一个都在前一个"历史版本"的基础上建立一个新的"历史版本",每 ...

  3. ES6中的Symbol类型

    前面的话 ES5中包含5种原始类型:字符串.数字.布尔值.null和undefined.ES6引入了第6种原始类型——Symbol ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个 ...

  4. HDU1027 Ignatius and the Princess II

    Problem Description Now our hero finds the door to the BEelzebub feng5166. He opens the door and fin ...

  5. Md5的加密 java实现

    百度百科对MD5的说明是: Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护. MD5即Mess ...

  6. yii2 获取从前台传过来的post数据

    第一次使用yii写接口的时候,直接用了$_POST获取post数据,发现会报400错误,根本无法获取到post数据,用$_GET却能获取get数据. 纠结了很久,然后查资料,发现原来yii中默认的开启 ...

  7. Azure 认知服务 (4) 计算机视觉API - 读取图片中的文字 (OCR)

    <Windows Azure Platform 系列文章目录> 微软Azure认知服务的计算机视觉API,还提供读取图片中的文字功能 在海外的Windows Azure认知服务的读取图片功 ...

  8. Qt5构建出错问题解决办法

    我之前用的Qt其他版本,因为一些原因我更换了Qt版本,从Qt5.9.1又更换到之前用的Qt5.3.2,但是发现无法build,问题提示如下: 19:54:03: 为项目untitled执行步骤 ... ...

  9. 根据百度,gps坐标获取天气

    楼主用的是阿里天气免费版,限制1000次,可以重复购买 下面放代码 var orgWindow = new OrganizeWindowProxy(WorkContext); var orgInfo ...

  10. oracle 通过同义词建立视图

    需要给予以下权限. GRANT CREATE VIEW TO tms;GRANT SELECT ANY table TO tms;GRANT SELECT ANY DICTIONARY TO tms;