算法系列2、分治算法
来源:互联网 发布:fstab自动挂载yum 编辑:程序博客网 时间:2024/05/02 05:56
- 1基本概念
- 2分治法适用的情况
- 3分治法的基本步骤
- 4设计程序的思维过程
- 5分治法的复杂性分析
- 6示例代码-归并排序
1、基本概念
字面上的解释是“分而治之”,就是把一个复杂的问题
1) 把它分成两个或多个更小的问题;
2) 分别解决每个小问题;
3) 把各小问题的解答组合起来,即可得到原问题的解答。
这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……
2、分治法适用的情况
分治法所能解决的问题一般具有以下几个特征:
1)原问题可以分解为多个子问题
- 这些子问题与原问题相比,只是问题的规模有所降低,其结构和求解方法与原问题相同或相似。
2) 原问题在分解过程中,递归地求解子问题。
- 由于递归都必须有一个终止条件,因此,当分解后的子问题规模足够小时,应能够直接求解。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
- 应能够采用某种方式、方法合并或构造出原问题的解。
不难发现,在分治策略中,由于子问题与原问题在结构和解法上的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想
3、分治法的基本步骤
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 求解:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
它的一般的算法设计模式如下:
Divide-and-Conquer(P)
1. if |P|≤n02. then return(ADHOC(P))3. 将P分解为较小的子问题 P1 ,P2 ,...,Pk4. for i←1 to k5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi6. T ← MERGE(y1,y2,...,yk) △ 合并子问题7. return(T)
其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,…,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,…,Pk的相应的解y1,y2,…,yk合并为P的解。
4、设计程序的思维过程
实际上就是类似于数学归纳法,找到解决本问题的求解方程公式,然后根据方程公式设计递归程序。
1、一定是先找到最小问题规模时的求解方法
2、然后考虑随着问题规模增大时的求解方法
3、找到求解的递归函数式后(各种规模或因子),设计递归程序即可。
5、分治法的复杂性分析
一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:
T(n)= k T(n/m)+f(n)
6、示例代码-归并排序
#include <stdlib.h>#include <stdio.h>void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex){ int i = startIndex, j=midIndex+1, k = startIndex; while(i!=midIndex+1 && j!=endIndex+1) { if(sourceArr[i] >= sourceArr[j]) tempArr[k++] = sourceArr[j++]; else tempArr[k++] = sourceArr[i++]; } while(i != midIndex+1) tempArr[k++] = sourceArr[i++]; while(j != endIndex+1) tempArr[k++] = sourceArr[j++]; for(i=startIndex; i<=endIndex; i++) sourceArr[i] = tempArr[i];}//内部使用递归void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex){ int midIndex; if(startIndex < endIndex) { midIndex = (startIndex + endIndex) / 2; MergeSort(sourceArr, tempArr, startIndex, midIndex); MergeSort(sourceArr, tempArr, midIndex+1, endIndex); Merge(sourceArr, tempArr, startIndex, midIndex, endIndex); }}int main(int argc, char * argv[]){ int a[8] = {50, 10, 20, 30, 70, 40, 80, 60}; int i, b[8]; MergeSort(a, b, 0, 7); for(i=0; i<8; i++) printf("%d ", a[i]); printf("\n"); return 0;}
- 算法系列2、分治算法
- 【算法系列】分治法
- 算法系列之分治
- 算法系列—分治法
- 洗牌算法2-分治
- 算法系列(一):分治策略--棋盘覆盖
- 面试笔试算法系列之分治法
- 趣学算法系列-分治法
- 分治算法
- 分治算法
- 分治算法?
- 【算法】分治
- 【算法】分治
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 利用runtime添加属性
- 详解Android开发中Activity的四种launchMode
- 【LeetCode】153. Find Minimum in Rotated Sorted Array
- pip安装使用详解
- Lab根据内容动态获取宽、高
- 算法系列2、分治算法
- OC编码规范
- Mac端通过Hexo搭建独立博客
- Python 图片下载PictureSpider
- Java并发编程:阻塞队列
- 2016猴年首一发,台州双线高防机房,速度快
- 关于FPGA中Speed Grade的说明
- iDB-数据库自动化运维平台
- shell