Java编程中实现归并排序算法的实例教程

 更新时间:2016年05月04日 11:37:16   作者:然则  
这篇文章主要介绍了Java编程中实现归并排序算法的实例教程,包括自底向上的归并排序的实现方法介绍,需要的朋友可以参考下

算法概述/思路
归并排序是基于一种被称为“分治”(divide and conquer)的策略。其基本思路是这样的:
1.对于两个有序的数组,要将其合并为一个有序数组,我们可以很容易地写出如下代码:

//both a and b is ascend.
public void merge(int[] a, int[] b, int[] c){
  int i=0,j=0,k=0;
  while (i<=a.length && j<=b.length){
    if (a[i]<=b[i]){
      c[k++]=a[i++];
    }
    else{
      c[k++]=b[j++];
    }
  }
  while (i<=a.length){
    c[k++]=a[i++];
  }
  while (j<=b.length){
    c[k++]=b[j++];
  }
}

容易看出,这样的合并算法是高效的,其时间复杂度可达到O(n)。
2.假如有一个无序数组需要排序,但它的两个完全划分的子数组A和B分别有序,借助上述代码,我们也可以很容易实现;
3.那么,如果A,B无序,怎么办呢?可以把它们再分成更小的数组。
4.如此一直划分到最小,每个子数组都只有一个元素,则可以视为有序数组。
5.从这些最小的数组开始,逆着上面的步骤合并回去,整个数组就排好了。
总而言之,归并排序就是使用递归,先分解数组为子数组,再合并数组。

例子
下面举例说明,假如要对数组a={2,1,3,5,2,3}进行排序,那么把数组划分为{2,1,3}和{5,2,3}两个子数组,这两个子数组排序后变为{1,2,3}和{2,3,5},然后对这两个数组进行归并操作便得到最终的有序数组。代码实现如下:

void sort(int[] a) {
  int[] aux = new int[a.length];  //辅助数组
  mergeSort(a, 0, a.length - 1, aux);
}

void mergeSort(int[] a, int lo, int hi, int[] aux) {
  if (hi <= lo)
    return;
  int mid = lo + (hi - lo) / 2;
  mergeSort(a, lo, mid, aux);
  mergeSort(a, mid + 1, hi, aux);
  merge(a, lo, mid, hi, aux);

}

void merge(int[] a, int lo, int mid, int hi, int[] aux) {
  int i = lo, j = mid + 1;
  for (int k = lo; k <= hi; k++) {
    aux[k] = a[k];
  }
  for (int k = lo; k <= hi; k++) {
    if (i > mid)
      a[k] = aux[j++];
    else if (j > hi)
      a[k] = aux[i++];
    else if (aux[i] <= aux[j])
      a[k] = aux[i++];
    else
      a[k] = aux[j++];

  }
}

另一种实现:自底向上的归并排序
在上面的实现中,相当于将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。将一个大的数组的排序划分为小数组的排序是自顶向下的排序。还有一种实现是自底向上的排序,即先两两归并,然后四四归并......代码实现如下:

void sort(int[] a) {
  int N = a.length;
  int[] aux = new int[N];
  for (int sz = 1; sz < N; sz += sz) {
    for (int lo = 0; lo < N - sz; lo += sz + sz) {
      //在每轮归并中,最后一次归并的第二个子数组可能比第一个子数组要小
      merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1), aux);
    }
  }
}

相关文章

  • java Springboot实现教务管理系统

    java Springboot实现教务管理系统

    这篇文章主要介绍了java Springboot实现教务管理系统的过程,文章围绕实现过程展开全文详细内容,具有一定的参考价值,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • Java接口返回省市区树形结构的实现

    Java接口返回省市区树形结构的实现

    本文主要介绍了Java接口返回省市区树形结构的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Java生成二维码的实现方式汇总

    Java生成二维码的实现方式汇总

    本文将基于Spring Boot介绍两种生成二维码的实现方式,一种是基于Google开发工具包,另一种是基于Hutool来实现,下面我们将基于Spring Boot,并采用两种方式实现二维码的生成,对于每一种方式还提供两种类型的二维码返回形式,需要的朋友可以参考下
    2023-09-09
  • SpringBoot自动装配的原理与使用

    SpringBoot自动装配的原理与使用

    在现代的软件开发中,依赖管理是一个关键的任务,随着应用程序规模的增长,手动管理对象之间的依赖关系变得越来越复杂,为了解决这个问题,Spring Boot提供了一种强大的功能,即自动装配,感兴趣想要详细了解可以参考下文
    2023-05-05
  • Java绘图库JFreeChart的使用教程

    Java绘图库JFreeChart的使用教程

    图表是一种以简单方式显示信息的图形,JFreeChart允许创建各种交互式和非交互式图表,本文主要介绍了Java绘图库JFreeChart的使用教程,感兴趣的可以了解一下
    2023-09-09
  • Java实现将数字日期翻译成英文单词的工具类实例

    Java实现将数字日期翻译成英文单词的工具类实例

    这篇文章主要介绍了Java实现将数字日期翻译成英文单词的工具类,结合完整实例形式分析了Java日期转换与字符串操作相关实现技巧,需要的朋友可以参考下
    2017-09-09
  • java基本教程之多线程基本概念 java多线程教程

    java基本教程之多线程基本概念 java多线程教程

    多线程是Java中不可避免的一个重要主体。下面是对“JDK中新增JUC包”之前的Java多线程内容的讲解,JUC包是由Java大师Doug Lea完成并在JDK1.5版本添加到Java中的
    2014-01-01
  • SpringBoot优雅地实现全局异常处理的方法详解

    SpringBoot优雅地实现全局异常处理的方法详解

    这篇文章主要为大家详细介绍了SpringBoot如何优雅地实现全局异常处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-08-08
  • Java实现简单LRU缓存机制的方法

    Java实现简单LRU缓存机制的方法

    这篇文章主要介绍了Java实现简单LRU缓存机制的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Java+Selenium设置元素等待的方法详解

    Java+Selenium设置元素等待的方法详解

    本文主要介绍如何使用java代码利用Selenium操作浏览器,某些网页元素加载慢,如何操作元素就会把找不到元素的异常,此时需要设置元素等待,等待元素加载完,再操作,感兴趣的可以了解一下
    2023-01-01

最新评论