描述:

自底向上的归并排序算法的思想就是数组中先一个一个归并成两两有序的序列,两两有序的序列归并成四个有序的序列,然后四个有序的序列归并八个有序的序列,以此类推,直到,归并的长度大于整个数组的长度,此时整个数组有序。需要注意的是数组按照归并长度划分,最后一个子数组可能不满足长度要求,这个情况需要特殊处理。自顶下下的归并排序算法一般用递归来实现,而自底向上可以用循环来实现。

Java代码实现:

package com.newtouch.data.sort;import com.newtouch.data.test.SortTestHelper;import java.util.Arrays;/*** 归并排序的算法实现* 实现复杂度o*/
public class MergeSortBU {//算法类不允许产生任何实例private MergeSortBU() {}//将arr[l...mid] 和arr[mid+1....r] 两部分进行归并private static void merge(Comparable[] arr, int l, int mid, int r) {Comparable[] aux = Arrays.copyOfRange(arr, l, r + 1);//初始化,i指向左半部分的起始;j指向右半部分其实索引位置mid+1int i = l, j = mid + 1;for (int k = l; k <= r; k++) {//
            if (i > mid) {//左半部分元素已经全部处理完毕arr[k] = aux[j - l];j++;} else if (j > r) {//右半部分元素已经全部处理完毕arr[k] = aux[i - l];i++;} else if (aux[i - l].compareTo(aux[j - i]) < 0) {//左半部分所指元素<右半部分所指元素arr[k] = aux[i - l];i++;} else {arr[k] = aux[j - l];j++;}}}public static void sort(Comparable[] arr) {int n=arr.length;for(int sz=1;sz<n;sz+=sz)for(int i=0;i<n-sz;i+=sz+sz)// 对于arr[mid] <= arr[mid+1]的情况,不进行mergeif( arr[i+sz-1].compareTo(arr[i+sz]) > 0 )merge(arr, i, i+sz-1, Math.min(i+sz+sz-1,n-1) );}public static void main(String[] args) {// Merge Sort是我们学习的第一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据// 注意:不要轻易尝试使用SelectionSort, InsertionSort或者BubbleSort处理100万级的数据// 否则,你就见识了O(n^2)的算法和O(nlogn)算法的本质差异:)int N = 1000000;Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);SortTestHelper.testSort("com.newtouch.data.sort.MergeSortBU", arr);return;}}

Java测试辅助类:

package com.newtouch.data.test;import java.lang.reflect.Method;
import java.lang.Class;
import java.util.Random;public class SortTestHelper {// SortTestHelper不允许产生任何实例private SortTestHelper() {}// 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR]public static Integer[] generateRandomArray(int n, int rangeL, int rangeR) {assert rangeL <= rangeR;Integer[] arr = new Integer[n];for (int i = 0; i < n; i++)arr[i] = new Integer((int) (Math.random() * (rangeR - rangeL + 1) + rangeL));return arr;}// 生成一个近乎有序的数组// 首先生成一个含有[0...n-1]的完全有序数组, 之后随机交换swapTimes对数据// swapTimes定义了数组的无序程度:// swapTimes == 0 时, 数组完全有序// swapTimes 越大, 数组越趋向于无序public static Integer[] generateNearlyOrderedArray(int n, int swapTimes) {Integer[] arr = new Integer[n];for (int i = 0; i < n; i++)arr[i] = new Integer(i);for (int i = 0; i < swapTimes; i++) {int a = (int) (Math.random() * n);int b = (int) (Math.random() * n);int t = arr[a];arr[a] = arr[b];arr[b] = t;}return arr;}// 打印arr数组的所有内容public static void printArray(Object[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]);System.out.print(' ');}System.out.println();return;}// 判断arr数组是否有序public static boolean isSorted(Comparable[] arr) {for (int i = 0; i < arr.length - 1; i++)if (arr[i].compareTo(arr[i + 1]) > 0)return false;return true;}// 测试sortClassName所对应的排序算法排序arr数组所得到结果的正确性和算法运行时间public static void testSort(String sortClassName, Comparable[] arr) {// 通过Java的反射机制,通过排序的类名,运行排序函数try {// 通过sortClassName获得排序函数的Class对象Class sortClass = Class.forName(sortClassName);// 通过排序函数的Class对象获得排序方法Method sortMethod = sortClass.getMethod("sort", new Class[]{Comparable[].class});// 排序参数只有一个,是可比较数组arrObject[] params = new Object[]{arr};long startTime = System.currentTimeMillis();// 调用排序函数sortMethod.invoke(null, params);long endTime = System.currentTimeMillis();assert isSorted(arr);System.out.println(sortClass.getSimpleName() + " : " + (endTime - startTime) + "ms");} catch (Exception e) {e.printStackTrace();}}
}

测试结果:

MergeSortBU : 322ms

转载于:https://www.cnblogs.com/caibixiang123/p/9545598.html

java归并排序自底向上实现:相关推荐

  1. java归并排序(含归并排序代码)

    目录 一:归并排序的思想 二:归并排序代码 三:归并排序结果​ 一:归并排序的思想 归并排序(Merge Sort) 当我们要排序这样一个数组的时候,归并排序法首先将这个数组分成一半.如图: 然后想办 ...

  2. java 归并排序 非递归_归并排序-递归及非递归的JAVA实现

    归并排序介绍 平均时间复杂度: O(NLogN) 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + LogN), 非递归:O(N) 稳 ...

  3. java归并排序代码_Java归并排序算法

    [java]代码库import java.util.Arrays; public class mergingSort { int a[]={49,38,65,97,76,13,27,49,78,34, ...

  4. 结合内存分析java归并排序_排序算法之归并排序(Mergesort)解析

    一.归并排序的优缺点(pros and cons) 耗费心思来理解它,总要有个理由吧:归并排序的效率达到了巅峰:时间复杂度为O(nlogn),这是基于比较的排序算法所能达到的最高境界 归并排序是一种稳 ...

  5. java归并排序算法

    归并排序的时间复杂度是:nlogn 主要是用到二路归并排序,也就是把两个有序集合合并为一个有序集合. 下面是我写的一个递归二路归并排序的算法: package algorithm;public cla ...

  6. java归并排序详解

    文章目录 一.归并排序原理 二.实例操作 三.实战代码 一.归并排序原理 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conque ...

  7. 归并排序-自底向上的二路归并

    自底向上二路归并算法的实现: #include <stdio.h> #include <malloc.h> #define MaxSize 20 typedef int Key ...

  8. Hark的数据结构与算法练习之归并排序

    算法说明: 归并排序的思路就是分而治之,将数组中的数字递归折半进行排序. 递归到最底层就只剩下有两个数字进行比较,再从底层往下进行排序合并.最终得出结果. 同样,语言描述可能对于不知道这个算法的人来说 ...

  9. Java数据结构和算法 - 递归

    三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,--中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...

  10. 常见排序算法详解 (收藏!)

    目录 冒泡排序 鸡尾酒排序 选择排序 插入排序 二分插入排序 希尔排序 归并排序 堆排序 快速排序 我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序. 排序算法大体可分为两种: ...

最新文章

  1. python多线程爬虫实例-python支持多线程的爬虫实例
  2. java世博会,反应原生失去的世博会
  3. sphinx python_如何使用Sphinx记录Python代码
  4. git push git pull 推送/拉取分支
  5. java发送请求_Java发送Http请求
  6. C#.NET验证码智能识别学习笔记---06 解决java jre问题:JTessBoxEditor.jar打开的时报找不到或无法加载主类 com.sun.tools.javac.Main错误
  7. Java编程思想(五) —— 多态(下)
  8. windows--CMD--命令大全
  9. 使用MongoDB Compass将JSON数据文件导入MongDB
  10. php GD绘图技术(实战)
  11. MySQL redo log 重做日志 原理 Oracle Redo Log 机制 小结
  12. -bash: ifconfig: command not found
  13. jsp 登陆成功后,显示登录的用户名
  14. Oracle导入dmp文件(cmd方式)
  15. 音频线视频线和同轴电缆的关系(同轴线除了外面的屏蔽网还有中间的绝缘塑料体,而音频线一般只有外面的屏蔽网)
  16. Teamviewer13版的安装及使用教程
  17. ADN8810 驱动
  18. java enum枚举型使用
  19. 什么是 Workflow?
  20. 禾赛科技“梦碎”科创板,还在专利官司中败退

热门文章

  1. Dgraph 1.2.8 发布,事务性分布式图形数据库
  2. SpringBoot2.x填坑(一):使用CROS解决跨域并解决swagger 访问不了问题
  3. 微信小程序电商实战-首页(下)
  4. razorPage三元运算符使用注意
  5. SQL语句统计每天、每月、每年、今天、昨天、本周、上周的数据
  6. C# 判断时间是否在 某一时间段内,判断时间是否是今天,获取今年第一天、最后一天,数字字符串转换为日期
  7. oracle服务器客户端配置文件,服务器 oracle 客户端配置文件
  8. OFFICE拼写语法检查:WORD是怎么做的?
  9. 传统武术家为什么看起来厉害?谈实战的重要性
  10. 编程基本功:BUG描述不要偷懒,不要误导