合并排序(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:合并是一种稳定的排序算法

堆排序快速排序希尔排序直接选择排序不是稳定的排序算法,

基数排序冒泡排序直接插入排序折半插入排序归并排序是稳定的排序算法。

 

 

 

 

 

posted @ 2017-10-19 22:27  三蜢  阅读(1077)  评论(0编辑  收藏  举报