合并排序(Java)-解析
合并排序-解析
? 算法設(shè)計有很多方法,前面說過的插入排序使用的是增量(incremental)方法:在排好子數(shù)組 A[ 1……j -1] 后,將元素 A[j] 插入,形成排好序的子數(shù)組 A[ 1……j]。
這次,要介紹的是另一設(shè)計策略,叫做 “分治法” (divide-and-conquer)。下面要用分治法來設(shè)計一個排序算法-合并排序(merge-sort),使其性能比插入排序好得多。
?
?
分治法
有很多算法在結(jié)構(gòu)上是遞歸的:為了解決一個給定的問題,算法要一次或多次地遞歸調(diào)用其自身來解決相關(guān)的子問題。這些算法通常采用分治策略:將原問題劃分為 n 個規(guī)模較小而結(jié)構(gòu)與原問題相似的子問題;遞歸地解決這些子問題,然后再合并其結(jié)果,就得到原問題的解。
分治模式在每一層遞歸上都有三個步驟:
分解(divide):將原問題分解成一系列子問題;
解決(conquer):遞歸地解決各個子問題,若子問題足夠小,則直接求解;
合并(combine):將子問題的結(jié)果合并成原問題的解。
?
?
?
合并排序算法完全依照了上述模式,直觀地操作如下:
分解:將 n 個元素分成各含 n/2 個元素的子序列;
解決:用合并排序法對兩個子序列遞歸地排序;
合并:合并兩個已排序的子序列以得到排序結(jié)果。
在對子序列排序時,其長度為 1 時遞歸結(jié)束。單個元素被視為是已排好序的。
?
合并排序在數(shù)組
A = <5 2 4 7 1 3 2 6> 上的處理過程。隨著算法的處理過程由底向上進(jìn)展,待合并的已排序列長度不斷增加。
?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);//復(fù)制左半部分 13 int[] right = Arrays.copyOfRange(arr, mid, length);//復(fù)制右半部分 14 merge_Sort(left);//遞歸左邊 15 merge_Sort(right);//遞歸右邊 16 merge(arr,left,right);//合并數(shù)組 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數(shù)組剩余,則后面依次復(fù)制給result 29 result[i++] = left[l++]; 30 } 31 while(r < right.length){//反之 32 result[i++] = right[r++]; 33 } 34 } 35 /******************************結(jié)束寫代碼******************************/ 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());//輸入數(shù)組大小 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());//輸入數(shù)組 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 }結(jié)果截圖:
?
?
PS:合并是一種穩(wěn)定的排序算法
堆排序、快速排序、希爾排序、直接選擇排序不是穩(wěn)定的排序算法,
而基數(shù)排序、冒泡排序、直接插入排序、折半插入排序、歸并排序是穩(wěn)定的排序算法。
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/denglw/p/6807185.html
總結(jié)
以上是生活随笔為你收集整理的合并排序(Java)-解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【UOJ】67 新年的毒瘤 【BZOJ】
- 下一篇: KMP算法的nextval[] 即优化n