java数据结构排序算法之归并排序详解

 更新时间:2017年05月29日 12:03:25   作者:android小猪  
这篇文章主要介绍了java数据结构排序算法之归并排序,结合具体实例形式详细分析了归并排序的原理、实现技巧与相关注意事项,需要的朋友可以参考下

本文实例讲述了java数据结构排序算法之归并排序。分享给大家供大家参考,具体如下:

在前面说的那几种排序都是将一组记录按关键字大小排成一个有序的序列,而归并排序的思想是:基于合并,将两个或两个以上有序表合并成一个新的有序表

归并排序算法:假设初始序列含有n个记录,首先将这n个记录看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2(n为奇数的时候,最后一个序列的长度为1)的有序子序列。在此基础上,再对长度为2的有序子序列进行亮亮归并,得到若干个长度为4的有序子序列。如此重复,直到得到一个长度为n的有序序列为止。这种方法被称作是:2-路归并排序(基本操作是将待排序列中相邻的两个有序子序列合并成一个有序序列)。

算法实现代码如下:

package exp_sort;
public class MergeSort {
  /**
   * 相邻两个有序子序列的合并算法
   *
   * @param src_array
   * @param low
   * @param high
   * @param des_array
   */
  public static void Merge(int src_array[], int low, int high,
      int des_array[]) {
    int mid;
    int i, j, k;
    mid = (low + high) / 2;
    i = low;
    k = 0;
    j = mid + 1;
    // compare two list
    while (i <= mid && j <= high) {
      if (src_array[i] <= src_array[j]) {
        des_array[k] = src_array[i];
        i = i + 1;
      } else {
        des_array[k] = src_array[j];
        j = j + 1;
      }
      k = k + 1;
    }
    // if 1 have,cat
    while (i <= mid) {
      des_array[k] = src_array[i];
      k = k + 1;
      i = i + 1;
    }
    while (j <= high) {
      des_array[k] = src_array[j];
      k = k + 1;
      j = j + 1;
    }
    for (i = 0; i < k; i++) {
      src_array[low + i] = des_array[i];
    }
  }
  /**
   * 2-路归并排序算法,递归实现
   *
   * @param src_array
   * @param low
   * @param high
   * @param des_array
   */
  public static void mergeSort(int src_array[], int low, int high,
      int des_array[]) {
    int mid;
    if (low < high) {
      mid = (low + high) / 2;
      mergeSort(src_array, low, mid, des_array);
      mergeSort(src_array, mid + 1, high, des_array);
      Merge(src_array, low, high, des_array);
    }
  }
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    int array1[] = { 38, 62, 35, 77, 55, 14, 35, 98 };
    int array2[] = new int[array1.length];
    mergeSort(array1, 0, array1.length - 1, array2);
    System.out.println("\n----------after sort-------------");
    for (int ii = 0; ii < array1.length; ii++) {
      System.out.print(array1[ii] + " ");
    }
    System.out.println("\n");
  }
}

代码解释:

归并排序中一趟归并要多次调用到2-路归并算法,一趟的归并的时间复杂度是O(n),合并两个已经排好序的表的时间显然是线性的,因为最多进行了n-1次比较,其中n是元素的总数。如果有多个数,即n不为1时,递归的将前半部分数据和后半部分数据各自归并排序,得到排序后的两部分数据,再合并到一起。

算法分析:

该算法是建立在归并操作(也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作)上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,它将问题分成一些小的问题然后递归求解,而治的阶段则是将分的阶段解得的各个答案修补到一块;分治是递归非常有力的用法。注意:与快速·排序和堆排序比较,归并排序最大的特点就是,它一种稳定的排序方法。速度仅次于快速排序,一般用于对总体无序,但是各子项相对有序的数列。

复杂度:

时间复杂度为:O(nlogn) ——该算法最好、最坏和平均的时间性能。
空间复杂度为 :O(n)
比较操作的次数介于(nlogn) / 2和 nlogn - n + 1之间。
赋值操作的次数是(2nlogn)。归并算法的空间复杂度为:0 (n)
很难用于主存排序(归并排序比较占用内存,主要问题在于合并两个排序的表需要线性附加内存,在整个算法中还要花费将数据拷贝到临时数组再拷贝回来这样的一些附加操作,其结果严重放慢了排序的速度)但是效率很高,主要用于外部排序,对于重要的内部排序应用而言,一般还是选择快速排序。

归并操作的步骤如下:

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾

归并排序的步骤如下(假设序列共有n个元素):

将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
重复步骤2,直到所有元素排序完毕

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • JAVA实现往字符串中某位置加入一个字符串

    JAVA实现往字符串中某位置加入一个字符串

    这篇文章主要介绍了JAVA实现往字符串中某位置加入一个字符串,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • SpringMVC中的DispatcherServlet请求分析

    SpringMVC中的DispatcherServlet请求分析

    这篇文章主要介绍了SpringMVC中的DispatcherServlet请求分析, DispatcherServlet作为一个Servlet,那么当有请求到Tomcat等Servlet服务器时,会调用其service方法,再调用到其父类GenericServlet的service方法,需要的朋友可以参考下
    2024-01-01
  • CyclicBarrier线程同步共享变量底层原理示例解析

    CyclicBarrier线程同步共享变量底层原理示例解析

    这篇文章主要为大家介绍了CyclicBarrier线程同步共享变量底层原理示例解析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Java中Object类常用的12个方法(小结)

    Java中Object类常用的12个方法(小结)

    Java 中的 Object 方法在面试中是一个非常高频的点,本文主要介绍了Java中Object类常用的12个方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Eclipse使用maven搭建spring mvc图文教程

    Eclipse使用maven搭建spring mvc图文教程

    这篇文章主要为大家分享了Eclipse使用maven搭建spring mvc图文教程,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Java报错:UnsupportedOperationException in Collections的解决方案

    Java报错:UnsupportedOperationException in Collection

    在Java编程中,UnsupportedOperationException是一种常见的运行时异常,通常在试图对不支持的操作执行修改时发生,它表示当前操作不被支持,本文将深入探讨UnsupportedOperationException的产生原因,并提供具体的解决方案和最佳实践,需要的朋友可以参考下
    2024-06-06
  • spring boot容器启动流程

    spring boot容器启动流程

    spring cloud是基于spring boot快速搭建的,今天咱们就看看spring boot容器启动流程,需要的朋友跟随脚本之家小编一起学习吧
    2018-01-01
  • SpringCloud微服务架构实战之微服务治理功能的实现

    SpringCloud微服务架构实战之微服务治理功能的实现

    这篇文章主要介绍了SpringCloud微服务架构实战之微服务治理,这些治理工具主要包括服务的注册与发现、负载均衡管理、动态路由、服务降级和故障转移、链路跟踪、服务监控等,需要的朋友可以参考下
    2022-02-02
  • java如何强制删除java程序占用的文件

    java如何强制删除java程序占用的文件

    这篇文章主要介绍了java如何强制删除java程序占用的文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Java中的方法、常量、变量、参数用例详解

    Java中的方法、常量、变量、参数用例详解

    在JVM的运转中,承载的是数据,而数据的一种变现形式就是“量”,量分为:常量与变量,我们在数学和物理学中已经接触过变量的概念了,在Java中的变量就是在程序运行过程中可以改变其值的量,这篇文章主要介绍了Java中的方法、常量、变量、参数,需要的朋友可以参考下
    2024-01-01

最新评论