分治法
程序员文章站
2022-03-03 08:32:59
...
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
分治法解题的一般步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
在分治策略中,由于子问题与原问题在结构和解法上的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归 并排序、堆排序、快速排序等,都存在有分治的思想。
二分查找
#include <stdio.h>
int BinarySearch(int *arr,int dst,int low,int high)
{
int mid = (low + high)/2;
if(dst == *(arr + mid))
return mid;
if(dst > *(arr + mid))
//low = mid + 1;
BinarySearch(arr,dst,mid + 1,high);
else
//high = mid - 1;
BinarySearch(arr,dst,low,mid - 1);
}
int main(void)
{
int arr[] = {1,3,5,8,9,10,13,17,19};
int high = sizeof(arr)/sizeof(int) - 1;
int low = 0;
int res = BinarySearch(arr,3,low,high);
printf("dst num is in pos of %d\n",res);
return 0;
}
快排
#include <stdio.h>
int swapPos(int *arr, int l, int r)
{
int i = l, j = r;
int x = *(arr + l);
while (i < j)
{
while(i < j && *(arr + j) >= x) j--;
if(i < j)
{
*(arr + i) = *(arr + j);
i++;
}
while(i < j && *(arr + i) < x) i++;
if(i < j)
{
*(arr + j) = *(arr + i);
j--;
}
}
// i = j
*(arr + i) = x;
return i;
}
void quickSort(int *arr, int l, int r)
{
if (l < r)
{
int i = swapPos(arr, l, r);
quickSort(arr, l, i - 1);
quickSort(arr, i + 1, r);
}
}
void printArr(int *arr,unsigned int len)
{
for(int i = 0; i < len; i++)
printf("%3d",*(arr + i));
printf("\n");
}
int main(void)
{
int arr[] = {4,9,1,6,3,7,11,2};
int len = sizeof(arr)/sizeof(int);
printf("original arr:");
printArr(arr,len);
quickSort(arr,0,len);
printf("new arr:");
printArr(arr,len);
return 0;
}
二分查找比较好理解,关于快排的原理解释可以参考:
白话经典算法系列之六 快速排序 快速搞定