算法这东西博大精深,又最能引人入胜。现在自己手头上的工作能用到算法的东西很少,慢慢淡忘了一些,今天来重温一下分治法。
分治法讲究分而治之,将一个复杂的大问题拆解成小的子问题。如果子问题还是很复杂,则继续拆解为更小的子问题。问题到最终肯定会转换为类似于1+1的问题。最明显的应用是在汉诺塔问题上。
分治法最先提出来是在2分查找上,在一个已排序序列中查找某个值。不妨就先来看看2分查找的应用:
int binary_search(int array[], int n, int value)
{
int left = 0;
int right = n -1;
while(left <= right)
{
int middle = left + ((right - left) >> 1);
if (array[middle] > value)
{
right = middle - 1;
}else if (array[middle] < value)
{
left = middle + 1;
}else
return middle;
}
return -1;
}
通过每次缩小一半的检索范围,大大的提高了效率。
接下来,看一下运用分治法的另一个例子,归并排序。
void merge_sort(int array[], int low, int high, int temp[]);
bool mergeSort(int array[], int n)
{
try{
int *temp = new int[n];
}catch(...)
{
return false;
}
merge_sort(array, 0, n-1, temp);
delete temp;
return true;
}
void merge_sort(int array[], int low, int high, int temp[])
{
if(low < high)
{
int mid = low + ((high - low)>>1) ;
merge_sort(array, low, mid, temp);
merge_sort(array, mid + 1, high, temp);
merge(array, low, mid, high, temp);
}
}
void merge(int array[], int low, int mid, int high, int temp[])
{
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
int p = 0;
while(begin1 <= end1 && begin2 <= end2)
{
if(array[begin1] < array[begin2])
{
temp[p++] = array[begin1++];
}else
{
temp[p++] = array[begin2++];
}
}
while(begin1 <= end1)
{
temp[p++] = array[begin1++];
}
while(begin2 <= end2)
{
temp[p++] = array[begin2++];
}
for(int i = 0; i < p; i++)
{
array[low + i] = temp[i];
}
}
归并算法的精髓就在merge_sort函数中,将一个问题转换为两个子问题,子问题分解后,将子问题的解进行合并。最后各个子问题的解得到了最终问题的解。
当然我看的这些都是浅层次关于分治法,分治法的运用非常多。继续学习总结。