版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
算法设计与分析引子-治国治国中国黑龙江省……北京市西城区……海淀区……北下关街道…………东城区……广东省孙子兵法“凡治众如治寡,分数是也”引子治国齐家引子治国齐家算法设计10000000万个整数的排序一个地图中10000000万个点,找出最近两个点分治与递归由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解,这自然导致递归过程的产生。分治是一种思想,递归是一种手段。生活中的递归─故事中的故事小孩子大都知道并复述过著名的“老和尚讲故事”:“从前有个庙,庙里有个老和尚,老和尚给小和尚讲故事,讲的故事是:从前有个庙,庙里有个老和尚,老和尚给小和尚讲故事,讲的什么故事呢?故事是……”Void
Story()
{
printf(“从前有个庙,庙里有个老和尚,老和尚给小和尚讲故事,\r\n”);
printf(“讲的什么故事呢?故事是:\r\n”);
Story();
}生活中的递归─画中画递归1.递归是一种特殊的迭代,只不过它在迭代前不知道要迭代多少次;2.递归的函数调用自身,而这个函数一定有参数,且参数会在迭代的过程中不断变化,步步逼近某个值;3.递归的函数中一定有那么一个分支是处理终点,而这个点就是递归出口。递归的两个要素递归函数的两个基本要素递归边界,也就是函数的初始值,每一个递归函数都必须具备非递归定义的初始值,否则,递归函数就无法计算。递推方程,用较小自变量的函数值来表示较大自变量的函数值,它是递归求解的依据,体现分治策略的核心要素。递归程序也包含类似的两部分边界处理部分,它是递归出口,决定何时结束递归调用。递归调用部分,它实现递归方程或递归操作过程。递归实例-1阶乘计算:从键盘输入正整数N(0<=N<=20),输出N!边界条件递推方程递归出口递归调用intmain(){intx=factorial(3);cout<<x<<endl;return0;}intfactorial(intn){//n=3if(n==0)return1;returnn*factorial(n-1);}intfactorial(intn){//n=2if(n==0)return1;returnn*factorial(n-1);}intfactorial(intn){//n=1if(n==0)return1;returnn*factorial(n-1);}intfactorial(intn){//n=0if(n==0)return1;returnn*factorial(n-1);}①②③④⑧⑦⑥⑤递归实例-2第n个月的兔子对数为F(n),它们按兔子的成熟属性可以分为两类:成熟兔子对=?新生兔子对=?
Fibonacci数列:意大利数学家Fibonacci在1202年写成的《计算之书》提出这样一个有趣的问题:“每对兔子每个月不多不少恰好能生一对(一雌一雄)新兔子,而且每对新生兔出生两个月后就成熟并具备生殖能力;另外,假定所有的兔子都不会死亡。假如养了初生的小兔一对,试问第n个月后共有多少对兔子?递归实例-2递归实例-3Stirling数:n个元素的集合{1,2,…,n}可以划分为若干个非空子集的集合。例如,当n=3时,集合{1,2,3}可以划分为5个不同的非空子集的集合如下:{{1},{2},{3}}{{1,2},{3}}{{1,3},{2}}{{2,3},{1}}{{1,2,3}}给定正整数n和m,计算出n个元素的集合{1,2,…,n}可以划分为多少个不同的由m个非空子集构成的集合。比如上例中含有1个子集的集合有1个,2个子集的集合有3个,3个子集的集合有1个。递归实例-3
递归实例-3把n个不同苹果放入m个相同盘子中,不允许盘子为空,请问总共有多少种方法?把n个相同苹果放入m个相同盘子中,不允许盘子为空,请问总共有多少种方法?分—将大规模的原问题分割成k
个更小规模的子问题,如果子问题的规模仍然不够小,则再划分为k个“子子”问题,如此递归地进行下去,直到子问题规模足够小(基础问题),很容易求出其解为止。分治算法总体思想原问题子问题子问题子问题
………
………………
分治算法总体思想治—求解规模足够小的子问题。原问题子问题子问题子问题
………………………√√√√√√√√√√√√√√√√√√√√√√√√分治算法总体思想合—将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。√√√√√………√√√√√√√√√√………………√√√√√√√√√√√√√√√√√√√√√√算法总体思想分治策略算法细分为三个阶段:Divide、Conquer、Combine。Divide阶段是把原问题分割成小问题,Conquer阶段是解决小问题,Combine阶段是运用小问题的解答,整理出原问题的解答。Divide√√√Conquer√√√Combine“分治合”策略分治策略基本原理
divide-and-conquer(P){(1)if(|P|<=n0)adhoc(P);//递归出口,用特定程序解决基础问题(2)divide
PintosmallersubinstancesP1,P2,...,Pk;//分解出子问题(3)for(i=1,i<=k,i++)
yi=divide-and-conquer(Pi);//递归求解各子问题(4)returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}分治策略基本原理设计划分策略,把原问题P分解成k个规模较小的子问题,这个步骤是分治算法的基础和关键,人们往往遵循两个原则:平衡子问题原则,分割出的k个子问题其规模最好大致相当;独立子问题原则,分割出的k个子问题之间重叠越少越好,最好k个子问题是相互独立,不存在重叠子问题。divide-and-conquer(P){(1)if(|P|<=n0)adhoc(P);//递归出口,用特定程序解决基础问题(2)divide
PintosmallersubinstancesP1,P2,...,Pk;//分解出子问题(3)for(i=1,i<=k,i++)
yi=divide-and-conquer(Pi);//递归求解各子问题(4)returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}分治策略基本原理merge合并子程序,把k个子问题的解合并得到原问题的解。合并子程序因求解问题而异,哪怕是同一个问题,如果第二步的划分策略不同,其合并子程序也往往不一样。divide-and-conquer(P){(1)if(|P|<=n0)adhoc(P);//递归出口,用特定程序解决基础问题(2)divide
PintosmallersubinstancesP1,P2,...,Pk;//分解出子问题(3)for(i=1,i<=k,i++)
yi=divide-and-conquer(Pi);//递归求解各子问题(4)returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}分治策略基本原理divide-and-conquer(P){(1)if(|P|<=n0)adhoc(P);//递归出口,用特定程序解决基础问题(2)divide
PintosmallersubinstancesP1,P2,...,Pk;//分解出子问题(3)for(i=1,i<=k,i++)
yi=divide-and-conquer(Pi);//递归求解各子问题(4)returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}
分治策略基本原理迭代求解:
分治策略基本原理划分策略是关键,总体上可以分为两大类:黑盒划分策略,此类方法根据问题的规模对原问题进行划分,而不考虑划分对象的属性值,所以形象地称之为黑盒划分;白盒划分策略,此方法根据划分对象的特定属性值(也称之为参照值)把对象集合划分为若干个子集。特别地,对于某些问题,根据白盒划分策略分割的部分子集可以直接排除,而不需要求解,可以认为减少了求解空间,称之为减治策略。黑盒划分典型问题—合并排序任务描述:任意给定一包含n个整数的集合,把n个整数按升序排列。输入:每测试用例包括两行,第一行输入整数个数,第二行输入n个整数,数与数之间用空格隔开。最后一行包含-1,表示输入结束。输出:每组测试数据的结果输出占一行,输出按升序排列的n个整数。样例输入:749386597761327-1样例输出:
13273849657697黑盒划分典型问题—合并排序黑盒划分典型问题—合并排序4938659776132749386597761327493865977613659776132738496597137638496597132776132738496576974938黑盒划分典型问题—合并排序3849659713277613273849657697黑盒划分典型问题—合并排序
黑盒划分典型问题—合并排序主程序:黑盒划分典型问题—合并排序4938659776132749386597136527761349386597977676132765973849659713273849657697132776137649383849黑盒划分典型问题—逆序对问题黑盒划分典型问题—逆序对问题枚举算法时间复杂度是O(n^2)当数组中元素的个数n比较少时,容易统计逆序对的数目数组中只有1个元素的话,逆序对的数目为0;数组中有2个元素,如果第一个元素大于第二个元素,则有1个逆序对,否则0个逆序对。数组中元素个数超过2,怎么办?黑盒划分典型问题—逆序对问题黑盒划分典型问题—逆序对问题C=C1+C2+C3计算C3有两种方法:
黑盒划分典型问题—逆序对问题38496597134076
A1A238>13{49,65,97}>13增加4个逆序对38<4038<{76}38不会再与A2中元素产生逆序对49>40{65,97}>40增加3个逆序对49<7649不会再与A2中元素产生逆序对65<7665不会再与A2中元素产生逆序对97>76增加1个逆序对黑盒划分典型问题—逆序对问题
…………A1A2C3+=(l+r)/2–i+1j++C3保持不变i++黑盒划分典型问题—逆序对问题黑盒划分典型问题—逆序对问题主程序:黑盒划分典型问题—逆序对问题493865977613274938659713652776134938659797767613276597384965971327384965769713277613764938384910112120白盒划分典型问题—快速排序白盒划分典型问题—快速排序白盒划分典型问题—快速排序白盒划分典型问题—快速排序49389776134938277665652738277697659713491313382749769765白盒划分典型问题—快速排序O(n)白盒划分典型问题—快速排序快速排序算法主程序白盒划分典型问题—快速排序快速排序的运行时间与划分是否对称有关:1)最坏情况,对于一个已经排好序的集合(比如{1,2,3,4,5,6}),调用快速排序的时间复杂度为:2)最好情况,每次划分所取的基准都恰好为中值,即每次划分都产生两个大小为n/2的区域,时间复杂度为:快速排序算法的性能取决于划分的对称性。通过修改算法partition,可以设计出采用随机选择策略的快速排序算法。在快速排序算法的每一步中,当数组还没有被划分时,可以在a[p:r]中随机选出一个元素作为划分基准,这样可以使划分基准的选择是随机的,从而可以期望划分是较对称的。白盒划分典型问题—快速排序void
randomizedQuickSort(int
iDatas[],int
iLeft,int
iRight){
if(iRight>iLeft) {
srand((unsigned)time(NULL));
int
iAncharIndex=rand()%(iRight-iLeft+1)+iLeft;
swap(iDatas[iAncharIndex],iDatas[iLeft]);
int
k=partition(iDatas,iLeft,iRight);
randomizedQuickSort(iDatas,iLeft,k-1);//对子集合A1排序
randomizedQuickSort(iDatas,k+1,iRight);//对子集合A3排序
}}
白盒划分典型问题—最接近点对枚举:O(n2)更高效率算法:O(nlog(n))为了使问题易于理解和分析,先来考虑一维的情形。此时,S中的n个点退化为x轴上的n个实数x1,x2,…,xn。最接近点对即为这n个实数中相差最小的2个实数。白盒划分典型问题—最接近点对假设我们用x轴上某个点m将S划分为2个子集S1和S2,基于平衡子问题的思想,用S中各点坐标的中位数来作分割点。递归地在S1和S2上找出其最接近点对{p1,p2}和{q1,q2},并设d=min{|p1-p2|,|q1-q2|},S中的最接近点对或者是{p1,p2},或者是{q1,q2},或者是某个{p3,q3},其中p3∈S1且q3∈S2。能否在线性时间内找到p3,q3?白盒划分典型问题—最接近点对白盒划分典型问题—最接近点对二维的情形:选取一垂直线l:x=m来作为分割直线。其中m为S中各点x坐标的中位数。由此将S分割为S1和S2。递归地在S1和S2上找出其最小距离d1和d2,并设d=min{d1,d2},S中的最接近点对或者是d,或者是某个{p,q},其中p∈S1且q∈S2。O(n^2)能找到(p,q),能否在线性时间内找到?白盒划分典型问题—最接近点对压缩空间的枚举:候选点p和q到直线l的距离不能超过d,则只需考虑区间P1和P2的范围;考虑P1中任意一点p,它若与P2中的点q构成最接近点对的候选者,则必有distance(p,q)<d。满足这个条件的P2中的点一定落在一个d×2d的矩形R中;由d的意义可知,P2中任何2个S中的点的距离都不小于d。由此可以推出矩形R中最多只有6个S中的点?证明:将矩形R的长为2d的边3等分,将它的长为d的边2等分,由此导出6个(d/2)×(2d/3)的矩形。若矩形R中有多于6个S中的点,则由鸽舍原理易知至少有一个(d/2)×(2d/3)的小矩形中有2个以上S中的点。设u,v是位于同一小矩形中的2个点,则distance(u,v)<d。这与d的意义相矛盾。最多只需要检查6×n/2=3n个候选者为了确切地知道要检查哪6个点,可以将p和P2中所有S2的点投影到垂直线l上。由于能与p点一起构成最接近点对候选者的S2中点一定在矩形R中,所以它们在直线l上的投影点距p在l上投影点的距离小于d。由上面的分析可知,这种投影点最多只有6个。因此,若将P1和P2中所有S中点按其y坐标排好序,则对P1中所有点,对排好序的点列作一次扫描,就可以找出所有最接近点对的候选者。对P1中每一点最多只要检查P2中排好序的相继6个点。白盒划分典型问题—最接近点对实现细节略!减治策略—基本原理减治策略:在分治算法中,如果划分的某个(或者某些)子问题与原问题的解无关或者与其它子问题等同,则这个(或者这些)子问题可以忽略,不再递归求解。原问题子问题子问题子问题
………
………
………
XX减治策略—基本原理乘方运算设a是给定的实数,计算a^n,其中n是自然数。减治策略:在分治算法中,如果划分的某个(或者某些)子问题与原问题的解无关或者与其它子问题等同,则这个(或者这些)子问题可以忽略,不再递归求解。减治策略—二分查找
减治策略—二分查找线性扫描O(n)减治策略—二分查找算法复杂度分析:每执行一次算法的while循环,待搜索数组的大小减少一半。因此,在最坏情况下,while循环被执行了O(logn)次。循环体内运算需要O(1)时间,因此整个算法在最坏情况下的计算时间复杂性为O(logn)。不要小看这个程序,面试出得最多的题!减治策略—线性时间选择给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素。例:求数组A[1:9]=[65,70,75,80,85,60,55,50,45]第7小元素partition[1:9]=[60,45,50,55,65,85,80,75,70]j=7q=5[6:9]=[85,80,75,70]j=2partition[6:9]=[70,80,75,85]j=2q=4[6:8]=[70,80,75]j=2partition[6:8]=[70,80,75]j=2q=1[7:8]=[80,75]j=1减治策略—线性时间选择int
randomizedSelect(int*a,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年设施农业建设与运营协议
- 二零二五年度企业应收账款保理还款合同3篇
- 电子竞技赛事赞助费用支付合同书
- 垃圾分类处理系统开发协议
- 智能电网技术合作协议
- 2025房地产合同商业房回租合同
- 2025门面转让合同格式范本
- 2025合同到期解除劳动合同协议书范本
- 2025别墅装修合同范本
- 2025装修设计委托合同书范文
- 八大危险作业检查表
- 村务监督业务培训课件
- 初三家长会语文教师发言
- 粤教版科学四年级上册全册试卷(含答案)
- 疼痛科护士的疼痛评估与疼痛程度划分
- 安全管理计划指标和指标体系
- 仓库物料盘点作业规范培训课件
- 无线网络技术满分期末大作业
- 2023无人机搭载红外热像设备检测建筑外墙及屋面作业
- 《西游记》电子版阅读-小学版
- 2021-2022学年北师大版六年级(上)数学寒假作业(一)
评论
0/150
提交评论