注意:
devide-and-conquer(P) {
if( |p|<=n0 ){
adhoc(P)
};
divide P into smaller subinstances P1,P2,`````PK;
for( i = 1;i <=k ;i++){
yi = divide-and-conquer(Pi);
};
rerturn merge(y1,y2,.....,yk);
}
其中,|p|表示问题P的规模;n0为不需要再分解问题的阈值;adhoc是基本子算法,可以直接求解;merge用于将子问题的解合并为原问题的解。
设a>=1和b>1是常数,f(n)是一个函数,T(n)是定义在非负整数集上的函数:T(n)=aT(n/b)+ O(n^d) 。
即有:
二分查找的设计思想:
/*
*二分查找(数组实现)
*@param {array} a 需要查找的已排好序的数组
*@param {int} low 数组的最低下标
*@param {int} high 数组的最高下标
*@param {int} x 被查找的数
*@return {array} a 排好序的数组
*/
void binarySearch(int a[] , int low , int high , int x ){
if(low > high){
return ;
};
int mid = (low+high)/2;
if(a[mid] == x){
return mid;
};
if(a[mid] > x){
return binarySearch(a , low , mid , x );
}else if( a[mid] < x ){
return binarySearch(a , mid , high , x );
};
}
二分归并排序设计思想:
/*
*二分归并数组排序
*
*/
void merge ( int a[ ], int low , int mid , int high ){
int b[1000];
int i = low;
int j = mid;
int k = 0;
while(i <= mid && j<=high ){
if( a[i] > a[j]){
b[k]=a[j];
j++;
k++;
} else {
b[k]=a[i];
i++;
k++;
};
if(i <= m){
for( int p = i; p<=m ;p++){
b[k++]=a[p];
};
} else {
for(int p=j;p<=high;p++){
b[k++]=a[p];
}
}
}
for(int p=low;p<=high;p++){
a[p]=b[p-low];
};
/*
*
*@param {array} a 乱序数组
*@param {int} low 数组的最低下标
*@param {int} high 数组的最高下标
*/
void MergeSort( int a[ ], int low , int high ) {
if(low
用首元素x作为划分标准,将输入数组A划分成不超过x的元素构成的数组Al,大于x的元素构成的数组Ar。其中Al和Ar从左到右存放在数组A的位置。
递归地对子问题Al和Ar进行排序,直到子问题规模为1。
int partition(int a[], int left, int right) {
int x = a[left];
while (left < right) {
while (left < right&&a[right] >= x) {
right--;
};
a[left] = a[right];
while (left < right&&a[left] <= x) {
left++;
};
a[right] = a[left];
};
a[left] = x ;
return left ;
}
void QSort(int a[],int low,int high){
if(low
分治法(尤其是二分法)非常适合用于存在某一个数并且查找该目标数的题目,同时也注意几个点:
简单来说,分治法的设计思想就是:将一个大的问题分解为性质相同规模较小的小问题,逐个击破,分而治之。
如有错漏,恳请指出。