合并排序(Java)-解析
合并排序-解析
算法设计有很多方法,前面说过的插入排序使用的是增量(incremental)方法:在排好子数组 A[ 1……j -1] 后,将元素 A[j] 插入,形成排好序的子数组 A[ 1……j]。
这次,要介绍的是另一设计策略,叫做 “分治法” (divide-and-conquer)。下面要用分治法来设计一个排序算法-合并排序(merge-sort),使其性能比插入排序好得多。
分治法
有很多算法在结构上是递归的:为了解决一个给定的问题,算法要一次或多次地递归调用其自身来解决相关的子问题。这些算法通常采用分治策略:将原问题划分为 n 个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。
分治模式在每一层递归上都有三个步骤:
分解(divide):将原问题分解成一系列子问题;
解决(conquer):递归地解决各个子问题,若子问题足够小,则直接求解;
合并(combine):将子问题的结果合并成原问题的解。
合并排序算法完全依照了上述模式,直观地操作如下:
分解:将 n 个元素分成各含 n/2 个元素的子序列;
解决:用合并排序法对两个子序列递归地排序;
合并:合并两个已排序的子序列以得到排序结果。
在对子序列排序时,其长度为 1 时递归结束。单个元素被视为是已排好序的。
合并排序在数组
A = <5 2 4 7 1 3 2 6> 上的处理过程。随着算法的处理过程由底向上进展,待合并的已排序列长度不断增加。
Java代码:
1 import java.util.*; 2 3 public class Merge_Sort { 4 5 6 /* 7 ******************************开始写代码******************************/ 8 static void merge_Sort(int[] arr){ 9 int length = arr.length; 10 int mid = length/2; 11 if(length > 1){ 12 int[] left = Arrays.copyOfRange(arr, 0, mid);//复制左半部分 13 int[] right = Arrays.copyOfRange(arr, mid, length);//复制右半部分 14 merge_Sort(left);//递归左边 15 merge_Sort(right);//递归右边 16 merge(arr,left,right);//合并数组 17 } 18 } 19 20 static void merge(int[] result, int[] left, int[] right) { 21 int i = 0, l = 0, r = 0; 22 while(l < left.length && r < right.length){ 23 if(left[l] < right[r] ) 24 result[i++] = left[l++]; 25 else 26 result[i++] = right[r++]; 27 } 28 while(l < left.length){//若left数组剩余,则后面依次复制给result 29 result[i++] = left[l++]; 30 } 31 while(r < right.length){//反之 32 result[i++] = right[r++]; 33 } 34 } 35 /******************************结束写代码******************************/ 36 37 38 public static void main(String[] args){ 39 Scanner in = new Scanner(System.in); 40 int[] res; 41 42 int _a_size = 0; 43 _a_size = Integer.parseInt(in.nextLine().trim());//输入数组大小 44 int[] _a = new int[_a_size]; 45 int _a_item; 46 for(int _a_i = 0; _a_i < _a_size; _a_i++) { 47 _a_item = Integer.parseInt(in.nextLine().trim());//输入数组 48 _a[_a_i] = _a_item; 49 } 50 51 merge_Sort(_a); 52 for(int _a_i=0; _a_i < _a.length; _a_i++) { 53 System.out.print(String.valueOf(_a[_a_i])+" "); 54 } 55 56 } 57 }
结果截图:
PS:合并是一种稳定的排序算法