标签:
一、基本思想
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
二、二分法
利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。
三、解题步骤
分治法解题的一般步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
四、应用场景
运用分治策略解决的问题一般来说具有以下特点:
1、原问题可以分解为多个子问题
这些子问题与原问题相比,只是问题的规模有所降低,其结构和求解方法与原问题相同或相似。
2、原问题在分解过程中,递归地求解子问题
由于递归都必须有一个终止条件,因此,当分解后的子问题规模足够小时,应能够直接求解。
3、在求解并得到各个子问题的解后
应能够采用某种方式、方法合并或构造出原问题的解。
不难发现,在分治策略中,由于子问题与原问题在结构和解法上的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想。
五、示例
1)二分搜索
二分搜索的前提是“数据必须有序”,也就是先要排序好。
(1)binarySearch.cpp
- #include <stdio.h>
-
- int binarySearch(int *array, int len, int value)
- {
- int low = 0;
- int high = len-1;
-
- int index = -1;
-
- while(low <= high)
- {
-
- int mid = (high + low)/2;
-
-
- if (value == array[mid])
- {
- index = mid;
- break;
- }
- else if (array[mid] < value)
- {
- low = mid + 1;
- }
- else
- {
- high = mid - 1;
- }
- }
-
- return index;
- }
- int main(void)
- {
- int array[] = {0,1,2,3,4,5,6,7,8,9};
-
- int len = sizeof(array)/sizeof(array[0]);
- int value = array[5];
-
- int index = binarySearch(array, len,value);
-
-
- if (-1 != index)
- {
- printf("the value is %d\n",array[index]);
- }
-
- return 0;
- }
(2)binarySearchDemo.java
- package algorithm.qdj.div;
-
- public class binarySearchDemo {
-
- public static void main(String[] args) {
-
- int[] array= new int[]{0,1,2,3,4,5,6,7,8,9};
- int value = array[5];
-
- int index = binarySearch(array, value);
- if (index != -1) {
- System.out.println("this value is "+array[index]);
- }
- }
-
- private static int binarySearch(final int[] array,final int value)
- {
- int low = 0;
- int high = array.length-1;
-
- int index = -1;
-
- while(low <= high)
- {
-
- int mid = (high + low)/2;
-
-
- if (value == array[mid])
- {
- index = mid;
- break;
- }
- else if (array[mid] < value)
- {
- low = mid + 1;
- }
- else
- {
- high = mid - 1;
- }
- }
-
- return index;
- }
- }
2)大数乘法
大数乘法,实现原理就是用计算机模拟人工手动计算,比如:123 x 45,只要会123x5那么,123x4就是一样的计算原理。
BigDiv.cpp
- #include <iostream>
- #include <string>
- using namespace std;
-
- string BigDiv(string num1, string num2)
- {
-
- int len1 = num1.size();
-
- int len2 = num2.size();
-
- int len = len1+len2;
-
- int *buf = new int[len];
-
- memset(buf,0,sizeof(int)*(len) );
-
-
-
- for (int it = 0,i = len2-1; i >= 0; --i,++it)
- {
- for (int jt = 0,j = len1-1; j >= 0; --j,++jt)
- {
-
- buf[len-1-it-jt] += ( (num1[j]-‘0‘)*(num2[i]-‘0‘) );
- }
- }
-
-
- for (int k = len-1; k > 0; --k)
- {
- if (buf[k] > 9)
- {
-
- buf[k-1] += (buf[k] / 10);
- buf[k] = (buf[k] % 10);
- }
- }
-
-
-
- int index = 0;
- while ( 0 == buf[index] )
- {
- ++index;
- }
-
-
- string result;
- for (int x = index; x < len; ++x)
- {
-
- result += (buf[x]+‘0‘);
- }
-
- return result;
- }
- void swap(string &num1, string &num2)
- {
- string buf;
- if ( ( num1.size() <= num2.size() ) && (num1 < num2))
- {
- buf = num1;
- num1 = num2;
- num2 = buf;
- }
- }
-
- int main(void)
- {
- string num1,num2;
-
-
- cin>>num1>>num2;
- swap(num1,num2);
-
- cout<<BigDiv(num1,num2)<<endl;
-
- return 0;
- }
3)快速排序
快速排序,就三步:
1)选择一个基准Select
2)将该Select摆放在合适的位置
3)重复1、2步骤
注意:选择的基准(Select),这个是自己随便选择的。所谓合适的位置,就是要使该位置前面的数字全部小于(大于)Select,后面的数字全部大于(小于)Select,同时一旦确定了Select的摆放位置,以后永远不再挪动Select。比如:下图中选择第一个数字9为基准,那么就要把9摆放在合适的位置(使9前面的数字全部小于9,后面的数字全部大于9,但不一定要有序)。下图为一趟对9的快速排序,直接找到了9应该摆放的位置。
- #include <stdio.h>
-
- void Qsort(int a[], int low, int high)
- {
- int Select = a[low];
- int i = low, j = high;
-
- if (i >= j)
- return;
- else
- {
- while (i < j)
- {
- while (a[j] > Select && i < j)
- --j;
- a[i] = a[j];
- while (a[i] <= Select && i < j)
- ++i;
- a[j] = a[i];
- }
- }
- a[i] = Select;
-
- Qsort(a, low, i-1);
- Qsort(a, i+1, high);
- }
-
- int main()
- {
- int i, a[5] = {13,4,7,8,2};
-
- Qsort(a, 0, 4);
- for (i = 0; i < 5; ++i)
- printf("%d ",a[i]);
-
- return 0;
- }
未完待续,示例更新中……
六、参考文献:
百度百科,分治算法,http://baike.baidu.com/view/1650802.htm
五大算法之分治算法
标签:
原文地址:http://www.cnblogs.com/qingdujun/p/4287093.html