master公式: T(n) = a * T(N/b) + O(N^d);
當:
log b A < d 時,程序的時間復雜度為:O(N^d);
log b A > d 時,程序的時間復雜度為:O(N^log b A);
log b A = d 時,程序的時間復雜度為:O(N^d * log N);
符合子問題規模是等規模的行為,均可使用master公式求解時間復雜度。
例:
/*
* 遞歸調用求最大值
* */
public static int process(int[] arr,int L,int R){
if(L==R){
return arr[L];
}
int mid = L + ((R-L)>>1); //求中點
int leftMax = process(arr,L,mid);
int rightMax = process(arr,mid+1,R);
return Math.max(leftMax,rightMax);
}
解析:
程序進行遞歸調用是,符合子問題規模是等規模(leftMax和rightMax);
a: 子問題調用的次數,本程序的次數為2次(leftMax和rightMax);
N:為母問題規模,本程序的母問題規模為N;
T(N/b): 子問題規模,本程序的子問題規模為:N/2(二分);
O(n^d): 子問題以為的時間復雜度,本程序為O(1)(求中點);
可得本程序的master公式為:T(N) = 2 * T(N/2) + O(1);
所以,本程序的時間復雜度為:T(N) = O(N)
注: 求中點公式: int mid = L + ((R - L ) >> 1) L:起點,R:終點
例子: 合並排序
//程序入口
public static void main(String[] args){
int[] arr = {1,4,4,2,6,1,67,89,3};
MergeSort(arr,0,arr.length-1);
System.out.print("數組排序為:");
for(int number:arr){
System.out.print(number+" ");
}
}
/*
* 歸並排序
*算法解析:
* 1、將數組進行二分,分成倆個數組leftArr和RigtArr
* 2、對其中一個數組,進行繼續遞歸,分別屬於這一層遞歸的倆個數組leftArr和RigtArr
* 3、當LR相同時,即說明已經分到只剩一個元素了,第一個遞歸開始返回
* 4、開始遞歸返回,獲取第二個值,此時的這一層的leftArr含有最后的一個元素,rightArr含有第二個值
* 5、將leftArr和rightArr中的元素,按照大小按序放進輔助數組help,再遍歷寫進原先的數組arr
* 6、遞歸返回一層,重復5的步驟,直至leftArr完成排序
* 7、進入rightArr,開始重復leftArr的排序步驟
* 8、完成對rightArr的排序
* 9、遞歸最后一層,對leftArr和rightArr重復5的步驟
* 10、完成排序
* */
public static void MergeSort(int[] arr, int L, int R){
if(L == R){
return;
}
int mid = L + ( (R - L) >>1);
MergeSort(arr,L,mid);
MergeSort(arr,mid+1,R);
merge(arr,L,mid,R);
}
/*
*對元素,按照大小放進輔助數組help,在存放會原先的數組
*/
public static void merge(int[] arr, int L,int mid, int R){
int[] help = new int[R-L+1]; //臨時存儲的數組
int i = 0;
int p1 = L;
int p2 = mid + 1; //分開為倆個數組后,數組首元素的下標;
while (p1 <= mid && p2 <= R ){ //比較數組元素大小,小的元素先進臨時存儲的數組,如果相等,默認左邊數組的元素進數組
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= mid){
help[i++] = arr[p1++];
}
while (p2 <= R){
help[i++] = arr[p2++];
}
//System.out.print("此時的help數組為:");
for(i = 0; i < help.length; i++){
arr[L + i] = help[i];
//System.out.print(help[i]+" ");
}
// System.out.print(" 此時的L為:"+L);
//System.out.println();
}
輸出結果:
數組排序為:1 1 2 3 4 4 6 67 89
解析:
T(N)母問題規模: 為數組長度,為N
T(N/d)子問題規模: 進行了倆次遞歸調用,每次的長度為數組長度的一半,即為N/2;
O(n)子問題以外的規模: 按照大小存儲數據到輔助數組help的時間復雜度為O(N),遍歷help存放到原數組arr的時間復雜度為O(N),所有子問題以外的時間復雜度為O(N);
所以合並算法的master公式為: T(N) = 2 * T(N/2) + O(N)
符合 log b A = d 的情況,所以合並算法的時間復雜度為: O(N*logN)
