Java排序算法三之归并排序的递归与非递归的实现示例解析

归并有递归和非递归两种。

归并的思想是:
1.将原数组首先进行两个元素为一组的排序,然后合并为四个一组,八个一组,直至合并整个数组;
2.合并两个子数组的时候,需要借助一个临时数组,用来存放当前的归并后的两个数组;
3.将临时数组复制回原数组对应的位置。

非递归的代码如下:

package mergesort;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
//归并排序的非递归算法
public class MergeSort{
  public static void main(String args[]){
    MergeSort mer = new MergeSort();
    int[] array = mer.getArray();
    System.out.println("OriginalArray:" + Arrays.toString(array));
    mer.mergeSort(array);
    System.out.println("SortedArray:" + Arrays.toString(array));
  }
  public int[] getArray(){
    Scanner cin = new Scanner(System.in);
    System.out.print("Input the length of Array:");
    int length = cin.nextInt();
    int[] arr = new int[length];
    Random r = new Random();
    for(int i = 0; i < length; i++){
      arr[i] = r.nextInt(100);
    }
    cin.close();
    return arr;
  }
  public void mergeSort(int[] a){
    int len = 1;
    while(len < a.length){
      for(int i = 0; i < a.length; i += 2*len){
        merge(a, i, len);
      }
      len *= 2;
    }
  }

  public void merge(int[] a, int i, int len){
    int start = i;
    int len_i = i + len;//归并的前半部分数组
    int j = i + len;
    int len_j = j +len;//归并的后半部分数组
    int[] temp = new int[2*len];
    int count = 0;
    while(i < len_i && j < len_j && j < a.length){
      if(a[i] <= a[j]){
        temp[count++] = a[i++];
      }
      else{
        temp[count++] = a[j++];
      }
    }
    while(i < len_i && i < a.length){//注意:这里i也有可能超过数组长度
      temp[count++] = a[i++];
    }
    while(j < len_j && j < a.length){
      temp[count++] = a[j++];
    }
    count = 0;
    while(start < j && start < a.length){
      a[start++] = temp[count++];
    }
  }
}

递归算法的实现代码如下:

package mergesort;

public class MergeSort {
  public static void mergeSort(int[] data,int left,int right){ //left,right均为数字元素下标
    if(left<right){
      int half=(left+right)/2;
      mergeSort(data,left,half);
      mergeSort(data,half+1,right);
      merge(data,left,right);
    }
  }
  public static void merge(int []a,int l,int h){
    int mid=(l+h)/2;
    int i=l;
    int j=mid+1;
    int count=0;
    int temp[]=new int[h-l+1];
    while(i<=mid&&j<=h){
      if(a[i]<a[j]){
        temp[count++]=a[i++];
      }else{
        temp[count++]=a[j++];
      }
    }
    while(i<=mid){
      temp[count++]=a[i++];
    }
    while(j<=h){
      temp[count++]=a[j++];
    }
    count=0;
    while(l<=h){
      a[l++]=temp[count++];
    }
  }
  public static void printArray(int arr[]){
    for(int k=0;k<arr.length;k++){
      System.out.print(arr[k]+"\t");
    }
  }
  public static int[] getArray(){
//   int[] data={4,2,3,1};
    int[] data={543,23,45,65,76,1,456,7,77,88,3,9};
    return data;
  }

  public static void main(String args[]){
    int[]a=getArray();
    System.out.print("数组排序前:");
    printArray(a);
    System.out.print("\n");
    mergeSort(a,0,a.length-1);
    System.out.print("归并排序后:");
    printArray(a);
  }
}

归并排序的时间复杂度为O(n*log2n),空间复杂度为O(n)

归并排序是一种稳定的排序方法。

到此这篇关于Java排序算法三之归并排序的递归与非递归的实现示例解析的文章就介绍到这了,更多相关Java排序算法之归并排序的递归与非递归内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

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

    本文实例讲述了java数据结构排序算法之归并排序.分享给大家供大家参考,具体如下: 在前面说的那几种排序都是将一组记录按关键字大小排成一个有序的序列,而归并排序的思想是:基于合并,将两个或两个以上有序表合并成一个新的有序表 归并排序算法:假设初始序列含有n个记录,首先将这n个记录看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2(n为奇数的时候,最后一个序列的长度为1)的有序子序列.在此基础上,再对长度为2的有序子序列进行亮亮归并,得到若干个长度为4的有序子序列.如此重

  • java实现归并排序算法

    归并排序算法思想: 分而治之(divide - conquer);每个递归过程涉及三个步骤 第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素. 第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作 第三, 合并: 合并两个排好序的子序列,生成排序结果. public static void mergeSort(int[] a, int[] tmp, int left, int right) { if (left < righ

  • Java排序算法之归并排序简单实现

    算法描述:对于给定的一组记录,首先将每两个相邻的长度为1的子序列进行归并,得到 n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列. package sorting; /** * 归并排序 * 平均O(nlogn),最好O(nlogn),最坏O(nlogn);空间复杂度O(n);稳定;较复杂 * @author zeng * */ public class MergeSort { public static void merge(int[] a,

  • 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[

  • Java经典排序算法之归并排序详解

    一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直

  • Java排序算法总结之归并排序

    本文实例讲述了Java排序算法总结之归并排序.分享给大家供大家参考.具体分析如下: 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作.和快速排序类似,让我们一起来看,归并在Java中的实现. 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的

  • 浅析java 归并排序算法

    归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))

  • Java分治归并排序算法实例详解

    本文实例讲述了Java分治归并排序算法.分享给大家供大家参考,具体如下: 1.分治法 许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题.这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: (1)分解原问题为若干子问题,这些子问题是原问题的规模较小的实例. (2)解决这些子问题,递归地求解各子问题.然而,

  • java 中归并排序算法详解

    java 中归并排序算法详解 归并排序算法,顾名思义,是一种先分再合的算法,其算法思想是将要排序的数组分解为单个的元素,每个元素就是一个单个的个体,然后将相邻的两个元素进行从小到大或从大到小的顺序排序组成一个整体,每个整体包含一到两个元素,然后对相邻的整体继续"合"并,因为每个整体都是排过序的,因而可以采用一定的算法对其进行合并,合并之后每个整体包含三到四个元素,继续对相邻的整体进行合并,直到所有的整体都合并为一个整体,最终得到的整体就是将原数组进行排序之后的结果. 对于相邻的整体,其

  • Java排序算法三之归并排序的递归与非递归的实现示例解析

    归并有递归和非递归两种. 归并的思想是: 1.将原数组首先进行两个元素为一组的排序,然后合并为四个一组,八个一组,直至合并整个数组: 2.合并两个子数组的时候,需要借助一个临时数组,用来存放当前的归并后的两个数组: 3.将临时数组复制回原数组对应的位置. 非递归的代码如下: package mergesort; import java.util.Arrays; import java.util.Random; import java.util.Scanner; //归并排序的非递归算法 publ

  • java 排序算法之归并排序

    目录 简单介绍 基本思想 思路分析 代码实现 对代码的一些改进 大数据量耗时测试 复杂度 简单介绍 归并排序(merge sort)是利用 归并 的思想实现的排序方法,该算法采用经典的 分治(divide-and-conquer)策略 : 分(divide):将问题分成一些小的问题,然后递归求解 治(conquer):将分的阶段得到的各答案「修补」在一起 即:分而治之 该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使

  • 图解Java排序算法之归并排序

    目录 基本思想 合并相邻有序子序列 代码实现 总结 基本思想 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之). 分而治之 可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现).分阶段可以理解为就是递归拆分子序列的过程,递归深

  • Java 排序算法整合(冒泡,快速,希尔,拓扑,归并)

    冒泡排序介绍 冒泡排序(Bubble Sort),又被称为气泡排序或泡沫排序. 它是一种较简单的排序算法.它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小:如果前者比后者大,则交换它们的位置.这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前.重复此操作,直到整个数列都有序为止! 冒泡排序图文说明 /* * a -- 待排序的数组 * n -- 数组的长度 */ public static void bub

  • 盘点几种常见的java排序算法

    目录 1.插入排序 2.分治排序法,快速排序法 3.冒泡排序 low版 4.冒泡排序 bigger版 5.选择排序 6. 归并排序 8. 堆排序 9. 其他排序 10. 比较 总结 1.插入排序 这个打麻将或者打扑克的很好理解, 比如有左手有一副牌1,2,4,7 ,来一张3的牌, 是不是就是手拿着这张牌从右往左插到2,4之间 一次插入排序的操作过程: 将待插元素,依次与已排序好的子数列元素从后到前进行比较,如果当前元素值比待插元素值大,则将移位到与其相邻的后一个位置,否则直接将待插元素插入当前元

  • Java排序算法总结之冒泡排序

    本文实例讲述了Java排序算法总结之冒泡排序.分享给大家供大家参考.具体分析如下: 前言:冒泡排序(BubbleSort)就是依次比较相邻的两个数,将小数放在前面,大数放在后面. 下面让我们一起    来看冒泡排序在Java中的算法实现. 冒泡排序是计算机的一种排序方法,它的时间复杂度为O(n^2),虽然不及堆排序.快速排序的O(nlogn,底数为2),但是有两个优点: 1."编程复杂度"很低,很容易写出代码: 2.具有稳定性,这里的稳定性是指原序列中相同元素的相对顺序仍然保持到排序后

  • Java排序算法之选择排序

    一.选择排序 选择排序就是在每一次遍历过程中将数组中值最小的排到当前的第一位. 总共需要(数组长度-1)次遍历,在每次遍历中假定第一位索引的值为最小值,然后与下一个值对比,如果最小索引所在值大于其他值就将小的那一个索引当作最小值索引,接着继续对比最小索引所在值与下一个索引的值,重复此操作,最终就会在此次遍历中得到最小值及其索引,将最小值与第一位的值进行交换,这样就将最小值放到了数组开头,完成本次遍历. 选择排序的时间复杂度为O(N^2) 二.代码实现 package com.example.al

  • java 排序算法之快速排序

    目录 简单介绍 基本思想 思路分析 代码实现 推导实现 完整实现 大数据量耗时测试 性能分析 简单介绍 快速排序(Quicksort) 是对 冒泡排序的一种改进. 基本思想 快速排序算法通过多次比较和交换来实现排序,其排序流程如下: (1)首先设定一个分界值(基准值),通过该分界值将数组分成左右两部分. (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边.此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值. (3)然后,左边和右边的数据可以

随机推荐