標籤:
一、分治演算法的原理
分治演算法就是將一個規模為N的問題分解成K個規模較小的子問題,這些子問題相互獨立且與原問題性質相同,求出子問題的解,就可以得出原問題的解
二、分治演算法的虛擬碼實現
合并演算法Merge
1 MERGE(A, p, q, r) 2 n1 ← q - p + 1 3 n2 ← r - q 4 create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1] 5 for i ← 1 to n1 6 do L[i] ← A[p + i - 1] 7 for j ← 1 to n2 8 do R[j] ← A[q + j] 9 L[n1 + 1] ← ∞10 R[n2 + 1] ← ∞11 i ← 112 j ← 113 for k ← p to r14 do if L[i] ≤ R[j]15 then A[k] ← L[i]16 i ← i + 117 else A[k] ← R[j]18 j ← j + 1
分治演算法:包括“分治”和“合并”
1 MERGE-SORT(A, p, r)2 if p < r3 then q ← ┕(p + r)/2┙4 MERGE-SORT(A, p, q)5 MERGE-SORT(A, q + 1, r)6 MERGE(A, p, q, r)
三、分治演算法的Java代碼實現
1 import java.util.Arrays; 2 import java.util.Comparator; 3 4 5 public class MergeSort { 6 7 /** 8 * 定義合并方法merge、mergesort方法 9 * 用泛型方法實現10 */11 public static <T> void merge(T[] t, int p, int q, int r, Comparator<? super T> c)12 {13 T[] left = Arrays.copyOfRange(t, p, q);14 T[] right = Arrays.copyOfRange(t, q, r);15 16 int indexleft = 0;17 int indexright = 0;18 19 for(int i = p; i < r; i++)20 {21 //注意:這裡只看演算法了,就完全沒管終止條件,要不然indexleft的值不斷往上走,肯定會越界的,因為整個程式是從p到r的,而且22 //indexleft和indexright還不一定哪個先結束呢,先結束了的話就沒法比較了,就需要針對剩下的做個處理了。。。23 //表示left到頭了24 if(indexleft >= left.length)25 {26 break;27 }28 //表示right到頭了29 if(indexright >= right.length)30 {31 System.arraycopy(left, indexleft, t, i, left.length-indexleft); 32 break;33 }34 if (c.compare(left[indexleft], right[indexright]) < 0)35 {36 t[i] = left[indexleft];37 indexleft++;38 }39 else40 {41 t[i] = right[indexright];42 indexright++;43 }44 }45 }46 47 public static <T> void mergeSort(T[] t, int p, int r, Comparator<? super T> c) 48 {49 if(p+1 < r)50 {51 int q = (p + r)/2;52 mergeSort(t, p, q, c);53 mergeSort(t, q, r, c);54 merge(t, p, q, r, c);55 }56 }57 58 public static <T> void mergeSort(T[] t, Comparator<? super T> c)59 {60 mergeSort(t, 0, t.length, c);61 }62 63 /**64 * @param args65 */66 public static void main(String[] args) {67 // TODO Auto-generated method stub68 Integer[] ints = new Integer[]{2, 0, 5, 23, 1, 4, 8, 56, 19};69 mergeSort(ints, new Comparator<Integer>(){70 public int compare(Integer o1, Integer o2){71 return o1 - o2;72 }73 });74 75 for (int i = 0; i < ints.length; i++)76 {77 System.out.print(ints[i] + " ");78 }79 System.out.println();80 }81 82 }
四、複雜度分析
合并部分的時間複雜度為O(N)
Java-分治演算法