1 问题描述
给定一组数据,使用合并排序得到这组数据的非降序排列。
2 解决方案
2.1 合并排序原理简介
引用自百度百科:
合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
合并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。合并排序也叫归并排序。
下面看一下具体排序示例:
排序性能分析:
2.2 具体编码
package com.liuzhen.chapterFive; public class Mergesort { //使用合并排序,获取数组A的非降序排列 public static void getMergesort(int[] A){ int lenA = A.length; //数组A的长度 if(lenA > 1){ int[] B = copyArray(A,0); //获取数组A中前一半元素 int[] C = copyArray(A,1); //获取数组A中后一半元素 getMergesort(B); //递归排序B中元素 getMergesort(C); //递归排序C中元素 Merge(B,C,A); //合并数组B和C,返回A的非降序序列 } } //返回数组A前一半或者后一半的元素,参数a用于判定前一半或者后一半元素 public static int[] copyArray(int[] A,int a){ int[] result; int len = A.length; if(a == 0){ //当a为0时代表返回数组A的前一半元素 result = new int[len/2]; for(int i = 0;i < len/2;i++) result[i] = A[i]; } else{ //a不为0时代表返回数组A的后一半元素 result = new int[len-len/2]; for(int i = 0;i < (len-len/2);i++) result[i] = A[len/2+i]; } return result; } //合并数组B和C,并将其变成非降序序列存入数组A中 public static void Merge(int[] B,int[] C,int[] A){ int i = 0,j = 0,k = 0; int lenB = B.length; //数组B的长度 int lenC = C.length; //数组C的长度 while(i<lenB && j<lenC){ if(B[i] < C[j]){ A[k] = B[i]; i++; } else{ A[k] = C[j]; j++; } k++; } if(i == lenB){ //当i等于lenB时,说明B数组中数已经全部存入A中,再把C数组中剩下的元素直接存入数组A中即可 while(j<lenC){ A[k] = C[j]; j++; k++; } } if(j == lenC){ //当j等于lenC时,说明C数组中数已经全部存入A中,再把B数组中剩下的元素直接存入数组A中即可 while(i<lenB){ A[k] = B[i]; i++; k++; } } } public static void main(String[] args){ int[] A = {8,3,2,9,7,1,5,4,4,45,3,2,22}; getMergesort(A); System.out.println("使用合并排序获得A数组的非降序序列结果如下:"); for(int i = 0;i < A.length;i++) System.out.print(A[i]+" "); } }
运行结果:
使用合并排序获得A数组的非降序序列结果如下:
1 2 2 3 3 4 4 5 7 8 9 22 45