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)