標籤:取出 main .so oid package htm string turn 組複製
package practice;import edu.princeton.cs.algs4.*;/* * 歸併排序 * 時間複雜度O(NlgN) N為數組長度 * 歸併排序在小數組上表現並不好可以用插入排序代替 */public class TestMain { public static void main(String[] args) { int[] a = new int[20]; for (int i = 0; i < a.length; i++) { int temp = (int)(StdRandom.random()*100); a[i] = temp; } Merge.sort2(a); for (int i : a) { System.out.print(i+" "); } }}class Merge{ private static int []anx; //輔助數組 /* * 自底向上的歸併排序(循序漸進) * 將數字兩兩分為一組,一直向上歸併 * 以下數字表示數組長度,假如要排一個長度為22的數組 * 2 2 2 2 2 2 2 2 2 2 2 * 4 4 4 4 4 2 * 8 8 6 * 16 6 * 22 */ public static void sort2(int[] a) { anx = new int[a.length]; for (int sz = 1; sz < a.length; sz += sz) { //將要歸併的大小(2*sz)翻倍 for (int lo = 0; lo < a.length - sz; lo += (sz + sz)) { //將數組分為(2*sz)大小的子數組,分別歸併 merge(a, lo, lo + sz -1, Math.min(lo + 2*sz -1, a.length - 1)); } } } /* * 自頂向下的歸併排序(化整為零) * 將原數組迴圈一分為二,直到數組長度為2,再將小數組兩兩迴圈歸併為原數組 * 以下數字表示數組長度,當被分數字為單數時,前面的數組長度多一 * 22 * 11 11 * 6 5 6 5 * 3 3 2 3 3 3 2 3 * 2 1 2 1 2 1 2 1 2 1 2 1 */ public static void sort1(int[] a) { anx = new int[a.length]; sort1(a, 0, a.length - 1); } private static void sort1(int []a, int lo, int hi) { if (lo >= hi) { return; } int mid = lo + (hi - lo)/2; //當被分數字為單數時,前面的數組長度多一 sort1(a, lo, mid); //一分為二歸併 sort1(a, mid + 1, hi); merge(a, lo, mid, hi); } /* * 原地歸併 */ public static void merge(int[] a, int lo, int mid, int hi) { int m = lo; int n = mid + 1; //當被分數字為單數時,將最中間的數字歸到前面的數組(與上面對應) int []anx = new int[hi+1]; for (int k = lo; k <= hi; k++) { anx[k] = a[k]; //將原數組複製到輔助數組 } //mid將數組分為A,B兩部分 for (int k = lo; k <= hi; k++) { if (m > mid) { //A中取完,將B數組剩餘部分存入a[] a[k] = anx[n++]; } else if (n > hi) { //B中取完,將A數組剩餘部分存入a[] a[k] = anx[m++]; } else if (anx[n] < anx[m]) { //A,B中分別取出第一個,比較,並將小數裝入a[] a[k] = anx[n++]; } else { a[k] = anx[m++]; } } }}
歸併排序動畫示範
http://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
歸併排序Java實現