一、分治策略概述
在算法中分治的思想是一種比較常見的思想,其步驟主要包括以下三步:
1.分解:將一個大問題分解爲多個小問題
2.解決:解決每個小問題,並返回結果
3.合併:將每個解決的小問題合併,最終將大問題解決
二、分治在歸併算法中的使用
使用分治的思想,比較典型的實例就是歸併排序算法,通過歸併排序的例子可以更好的理解分治策略。
給出一個數組:
sequence = {3,9,1,4,5,6,8,2,7};
圖1
如圖1,原來的8位數組被分成2個4位數組,最後被分爲1位數組,1位數組是不可再分的最小處理單元,處理完成後返回到2位數組,對2位數組排序後返回到4位數組,以此類推,最後返回兩個排序好的4位數組,再對這兩個數組進行排序,最後得到排好序的8位數組。
三、時間複雜度分析
每一層都是cn的複雜度,共有logn+1層(包括cn層),所以複雜度是cn(logn+1),從宏觀角度來說就是O(nlogn)。
四、歸併的java實現:
public class Merge {
static int[] sequence = {3,9,1,4,5,6,8,2,7};
static void mergeSort(int low,int mid,int high){
//max作爲標誌位,表明數組到底了
int max = 1000;
int length1 = mid-low+1;
int length2 = high-mid;
//用於存儲左元素
int[] tempSeq1 = new int[length1+1];
//用於存儲右元素
int[] tempSeq2 = new int[length2+1];
for(int i=0;i<length1;i++){
tempSeq1[i] = sequence[low+i];
}
tempSeq1[length1] = max;
for(int j=0;j<length2;j++){
tempSeq2[j] = sequence[mid+1+j];
}
tempSeq2[length2] = max;
int i = 0;
int j = 0;
for(int k=0;k<=high-low;k++){
if(tempSeq1[i]<=tempSeq2[j]){
sequence[low+k] = tempSeq1[i];
i++;
}else{
sequence[low+k] = tempSeq2[j];
j++;
}
}
}
static void doMerge(int low,int high){
//如果low<high說明還有多個元素
if(low<high){
int mid = (low+high)/2;
//左元素的分治
doMerge(low,mid);
//右元素的分治
doMerge(mid+1,high);
//具體的排序方法
mergeSort(low,mid,high);
}
}
//進行歸併算法
public static void main(String[] args) {
doMerge(0,sequence.length-1);
for(int i=0;i<sequence.length;i++){
System.out.println(sequence[i]);
}
}
}