收藏 分享(赏)

引论-递归与分治.ppt

上传人:HR专家 文档编号:6006216 上传时间:2019-03-23 格式:PPT 页数:71 大小:1.98MB
下载 相关 举报
引论-递归与分治.ppt_第1页
第1页 / 共71页
引论-递归与分治.ppt_第2页
第2页 / 共71页
引论-递归与分治.ppt_第3页
第3页 / 共71页
引论-递归与分治.ppt_第4页
第4页 / 共71页
引论-递归与分治.ppt_第5页
第5页 / 共71页
点击查看更多>>
资源描述

1、,算法设计与分析Design and Analysis of Computer Algorithm 刘云华 王波兴,2,参考教材,王晓东 算法设计与分析(第2版),清华大学出版社,2008 周培德 计算几何算法分析与设计(第2版) 清华大学出版社,2005,第一章 算法概述,第二章 递归与分治策略,第三章 动态规划,第四章 贪心算法,第五章 回朔法,第六章 分支限界法,第七章 概率算法,第八章 NP完全性理论简介,算法设计与分析 目录,算 法 概 述,Algorithm Introduction,第一章,介绍算法设计的基本概念 及算法分析的方法和准则.,算法设计与分析,5,一系列将问题的输入转

2、换为输出的计算或操作步骤。,2. 计算机算法与人工算法,算法设计与分析 算法概述,1.1 算法 Algorithm 1. 算法定义,有些问题没有计算机算法.,有些问题计算机算法与人工算法不同.,2).确定性 definiteness 算法的每个步骤必须有明确的意义,对每种可能的情况,算法都要给出确定的操作.,1).有穷性 finiteness算法必须在执行有穷步后终止,且每一步均在有限时间内完成,3).能行性effectiveness算法中的每个步骤是能够实现的,算法执行结果要达到预期目的,3.计算机算法的一般特征,4).有0个或多个输入项,至少有一个输出项.,6,算法设计与分析 算法概述,数

3、值型算法:算法中的基本运算为算术运算.,非数值型算法:算法中的基本运算为逻辑运算.,串行算法:串行计算机上执行的算法.,并行算法:并行计算机上执行的算法.,从处理方式上,6. 算法分类,从解法上,5.算法描述语言,1).数据: 运算序列中作为运算对象和结果的数据.2).运算: 运算序列中的各种运算:赋值,算术和逻辑运算 3).控制和转移: 运算序列中的控制和转移.,4.算法的三个要素,自然语言,数学语言,流程图,程序设计语言等等.,7,算法设计与分析 算法概述,7.问题的求解过程,2)建立数学模型(UML),1)问题的陈述,3)算法设计,4)算法的正确性证明,5)算法的程序实现,6)算法分析,

4、用科学规范的语言,对所求解的问题做准确的描述.,通过对问题的分析,找出其中的所有操作对象及操作对象之间的关系并用数学语言加以描述.,根据数学模型设计问题的计算机求解算法.,证明算法对一切合法输入均能在有限次计算后产生正确输出.,对执行该算法所消耗的计算机资源进行估算.,将算法正确地编写成机器语言程序.,8,算法设计与分析 算法概述,1.2 算法复杂性分析 1.复杂性的计量,显然,它与问题的规模,算法的输入数据及算法本身有关.,将时间复杂性和空间复杂性分别考虑,并用T和S表示.则 T=T(N,I,A) S=S(N,I,A)将A隐含在函数名中,则 T=T(N,I,A) 简化为T=T(N,I),算法

5、的复杂性:算法执行所需的时间和空间的数量.,令 N:问题的规模 I:输入数据 A:算法本身 则算法的复杂性 C=F (N,I,A),设一台抽象计算机提供的元运算有k种,分别记作O1 ,Ok 设这些元运算每执行一次所需时间分别为t1 , t2,tk , 设算法A中用到Oi的次数为 ei, i=1,k,则 ei= ei(N,I ),T=T(N,I)=,9,算法设计与分析 算法概述 算法的复杂性,最好情况:Tmin(N) = T(N,I) = = = 最坏情况:Tmax(N) = T(N,I) = = 平均情况:Tavg(N) = =,例 题1-1,其中 DN:规模为N的所有合法输入的集合I*: D

6、N中达到Tmax (N)的一个输入: DN中达到Tmin (N)的一个输入 P(I): 出现输入为I的概率,算法设计与分析,已知不重复且从小到大排列的m个整数的数组A1.m,m=2K,K 为正整数.对于给定的整数c,要求找到一个下标i,使得Ai=c.找不到返回0.,function search(c) i:=1; awhile Aic and im do 2mti:=i+1; (m-1) (s+a)if Ai=c tthen search:=i; else search:=0; a,算法1-1:顺序查找,例 题 1-1,分析:问题的规模为m,设元运算执行时间为赋值:a,判断:t,加法:s, 并

7、设c在A中.,最好情况Tmin (m)=2a+3t,最坏情况Tmax(m) =(m+1)a+(2m+1)t+(m-1)s,平均情况Tavg(m)=0.5(m+3)a+(m+2)t+0.5(m-1)s,算法设计与分析,算法1-2:二分查找 (假定c是A的最后一元),例 题 1-1,分析:问题规模为m,元运算执行时间设为赋值a,判断t, 加法s, 除法d, 减法b.,最坏情况Tmax(m) = 8a+4t+2s+d+(2a+2s+3t+d) logm,function b-search(c) L:=1; U:=m; 2afound:=false; awhile not found and U=L

8、do t (logm+2) i:=(L+U)div2; (a+s+d)(logm+1) if c=Ai t (logm+1)then found:=true aelse if cAi t (logm+1)then L:=i+1 (s+a)(logm+1)else U:=i-1 if found athen b-search:=i else b-search:=0 a,在数学上,T(n)与 有相同的最高阶项.可取 为略去T(n)的低阶项后剩余的主项.当n充分大时我们用 代替T(n)作为算法复杂性的度量,从而简化分析.,设T(n)为算法A的时间复杂性函数,则它是n的单增函数,如果存在一个函数 使得

9、当n ,有(T(n)- ) / T(n)0 称 是T(n)当 n 时的渐进性态或 渐进复杂性.,12,算法设计与分析 算法概述 算法的复杂性,2 复杂性的渐进性态 1).渐进性态,例如 T(n)=3n2+4nlogn+7, 则 可以是3n2.,若进一步假定算法中所有不同元运算的单位执行时间相同,则可不考虑 所包含的系数或常数因子。,渐进分析适用于n充分大的情况,当问题的规模很小时,或比较的两算法同阶时,则不能做这种简化.,13,算法设计与分析 算法概述 算法的复杂性,2).渐进性态的阶,又如算法1-1中,Tmin (m)=2a+3t,Tmax(m)=(m+1)a+(2m+1)t+(m-1)s,

10、Tmin (m)=O(1),Tmax(m)=O(m),例如,3n=O(n),n+1024=O(n),n2=O(n3) ?,n3=O(n2) ?,2n2+11n-10=O(n2),若存在正常数c和自然数N0 使得当 N N0 时,有f(N)cg (N) 则称函数 f(N )在N充分大时有上界, 且 g(N)是它的一个上界, 记为 f(N) =O(g (N) ) , 也称 f(N) 的阶不高于g (N) 的阶.,设f(N)和 g (N) 是定义在正整数集上的正函数,(1)大O表示法 (算法运行时间的上限 ),14,算法设计与分析 算法概述 算法的复杂性,例如 估计如下二重循环算法在最坏情况下时间复

11、杂性T(n2)的阶.,分析:内循环体只需O(1)时间,故,for i:= 1 to n dofor j:=1 to i dos1,s2,s3,s4 ; s1,s2,s3,s4为单一赋值语句,外循环共需,1. O(f)+O(g)=O(max(f,g)2. O(f)+O(g)=O(f+g)3. O(f)O(g)=O(fg)4. 如果 g(n)=O(f(n),则 O(f)+O(g)=O(f) 5. f=O(f)6. O(cf(n)=O(f(n),运 算 法 则,内循环共需,15,算法设计与分析 算法概述 算法的复杂性,(2)大表示法 (算法运行时间的下限),f(N) =(g(N) ) 当且仅当 f(

12、N) =O(g (N) ) 且f(N)=(g (N) ) 称函数f(N)与g (N)同阶.,算法的渐进复杂性的阶对于算法的效率有着决定性的意义: 多项式阶算法(有效算法):时间复杂性与规模N 的幂同阶. 指数阶算法:时间复杂性与规模N 的一个指数函数同阶. 最优算法:时间复杂性达到其下界的算法.,如果正常数c和自然数N0使得当 N N0 时, 有f(N)cg (N) 则称函数f(N)在N充分大时有下限, 且 g(N)是它的一个下限,记为f(N) = (g (N) ) 也称f(N)的阶不低于g(N)的阶。,(3)表示法,16,算法设计与分析 算法概述 算法的复杂性,图1 时间函数的增长率,常见的

13、多项式阶有:,O(1),O(logn),O(n),O(nlogn),O(n2),O(n3),O(2n),O(n!),O(nn),常见的指数阶有:,对规模较小的问题,决定算法 工作效率的可能是算法的简 单性而不是算法执行的时间.,当比较两个算法的效率时, 若两个算法是同阶的,必须进 一步考察阶的常数因子才能 辨别优劣.,17,算法设计与分析 算法概述 算法的复杂性,3.渐进分析时间复杂性渐进阶分析的规则:(最坏情况)1). 赋值,比较,算术运算,逻辑运算,读写单个变量(常量)只需1单位时间2). 执行条件语句 if c then S1 else S2 的时间为TC +max(TS1,TS2).

14、3). 选择语句 case A of a1: s1;a2: s2;.; am: sm 需要的时间为 max(TS1,TS2 ,., TSm).4). 访问数组的单个分量或纪录的单个域需要一个单位时间.5). 执行for循环语句的时间=执行循环体时间*循环次数.6). while c do s (repeat s until c)语句时间=(Tc+Ts)*循环次数.7). 用goto从循环体内跳到循环体末或循环后面的语句时,不需额外时间8). 过程或函数调用语句对非递归调用,根据调用层次由里向外用规则1-7进行分析; 对递归调用,可建立关于T(n)的递归方程,求解该方程得到T(n).,例 题1-

15、1,算法设计与分析,算法1-2:二分查找 (假定c是A的最后一元),例 题 1-1,分析:问题规模为m,元运算执行时间设为赋值a,判断t, 加法s, 除法d, 减法b.,最坏情况Tmax(m) = 8a+4t+2s+d+(2a+2s+3t+d) logm=14+8logm,function b-search(c) L:=1; U:=m; 2found:=false; 1while not found and U=L do Logm+2 i:=(L+U)div2; 3 if c=Ai 1then found:=true ( 1)else if cAi 1then L:=i+1 2else U:=

16、i-1 if found 1then b-search:=i else b-search:=0 1,Logm+1,算法设计与分析,已知不重复且从小到大排列的m个整数的数组A1.m,m=2K, K为正整数.对于给定的整数c,要求找到一个下标i,使得Ai=c.找不到返回0.,例 题 1-1,function b-search(c,L,U) if Uc then 1 b-search:= b-search(c,L, index-1); 3+T(m/2) else b-search:= b-search(c,index+1,U); 3+T(m/2); ,设T(m)是b-search在最坏情况下的时间复

17、杂性,则T(m)满足如下递归方程:,2 m=0,13 m=1,11+T(m/2) m1,T(m)=,解得: T(m) =11logm+13= (logm),算法1-3:二分查找递归算法,算法设计与分析,求Fibonacci数列的前N项 a0, a1, aN 其中, a0=0, a1=1, ai= ai-1+ ai-2 算法1-4,Procedure seq(n)function A(n) if n=0 then 1 A:=0 1else if n=1 then 1A:=1 1 else A:=A(n-1)+A(n-2) 6+F(n-1)+F(n-2) ; if n0 then 1errorel

18、se for i:=0 to n do writeln (A(i) (1+F(i);,设F(n)是函数A在最坏情况下的时间复杂性,则F(n)满足如下递归方程:,设过程seg在最坏情况下的时间复杂性为T(n),则 T(n)=1+ (1+F(i),2 n=0,3 n=1,8+ F(n-1)+ F(n-2) n1,F(n)=,例 题 1-2,21,算法设计与分析 算法概述 算法的复杂性,4).套用公式法若递归方程形如:T(n)=aT(n/b)+ f(n),可根据f(n)的不同情况套用公式1)若0,使得 f(n)=O(n logb a-),则T(n)=(n logb a)2)若f(n)=(n logb

19、 a), 则T(n)=(n logb a logn)3)若0,使得f(n)=(n logb a+),且 c1, 当n充分大时有a f(n/b) c f(n), 则 T(n)= (f(n),设a0 ,a1,an,是任意数列,称 f(x)=a0+a1x+ anxn+为数列的母函数 若取数列为算法的时间复杂性函数 T(n) ,则其母函数为:f(x)=T(0)+T(1) x+ T(n) xn 若能由T(n)的递归方程求出T(n)的母函数,其展开式第n项系数即为T(n).,4 递归方程解的渐进阶 1).母函数法,2).迭代法将递归方程的的右端项通过迭代展开成级数,然后估计级数和的渐进阶.,3).数学归纳

20、法(代入法)先估计递归方程的显式解,再用数学归纳法证明.,22,算法设计与分析 递归与分治,第二章 递归与分治(Divide and Conquer) 2.1 递归的概念,例1. 阶乘函数 f(n) =n!=n*(n-1)*(n-2)*3*2*1=n*(n-1)!=n*f(n-1) int factorial(int n) int f;if(n=0) f=1;else f =n* factorial(n-1); /调用自身函数return f; ,直接或间接地调用自身的算法称为递归算法.,23,算法设计与分析 递归与分治,Class Factorial public int n, f;Fact

21、orial(m) n=m; f=1; ; int factorial(int n) Factorial *p;for(int i=n; i0; i-) p=new Factorial(i); PushStack(p); Factorial *CurOb; Popup( ,递归程序的栈实现,24,算法设计与分析 递归与分治,Fibonacci 数列: F(n)=F(n-1)+F(n-2), F(0)=F(1)=1,递归代表一种计算规则, 有时有函数表示结果,有时没有.,整数划分问题 n=n1+n2+nk, 划分数p(n)计算的递归方法,有函数表示,无函数表示,25,算法设计与分析 递归与分治,例

22、5 整数划分问题 将正整数n表示成一系列正整数之和:n=n1+n2+nk, 其中n1n2nk1,k1。 正整数n的这种表示称为正整数n的划分。求正整数n的不 同划分个数。,例如正整数6有如下11种不同的划分:6;5+1;4+2,4+1+1;3+3,3+2+1,3+1+1+1;2+2+2,2+2+1+1,2+1+1+1+1;1+1+1+1+1+1。,26,算法设计与分析 递归与分治,(4) q(n,m)=q(n,m-1)+q(n-m,m),nm1; 正整数n的最大加数n1不大于m的划分由n1=m的划分和 n1m-1 的划分组成。,(3) q(n,n)=1+q(n,n-1); 正整数n的划分由n1

23、=n的划分和n1n-1的划分组成。,例5 整数划分问题 在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。,27,算法设计与分析 递归与分治,例5 整数划分问题 前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。 在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。,正整数n的划分数p(n)=q(n,n)。,m=n的划分只

24、有一个,最大加数达是m的划分个数等于将m从n中减去后n-m中最大加数是m的划分个数,28,例6 Hanoi塔问题 设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则: 规则1:每次只能移动1个圆盘; 规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上; 规则3:在满足移动规则1和2的前提下,可将圆盘移至a,b,c中任一塔座上。,29,算法设计与分析 递归与分治,递归代表一种计算规则, 有时其计算出的实现过程很难人工模拟.

25、,用已知方法将上n-1盘, 从a移到c,c,a,b,void Hanoi (int n, int a, int b, int c) if(n0) Hanoi(n-1, a, c, b);move(a,b);Hanoi(n-1,c, b, a); ,设对于任意n,方法已知(实际未知),将第n盘, 从a移到b,用已知方法将上n-1盘, 从c移到b,递归小结,优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。,缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。,算法设计与分析 递归与分治,解决方法:在递归算

26、法中消除递归调用,使其转化为非递归算法。 1、采用一个用户定义的栈来模拟系统的递归调用工作栈。该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。 2、用递推来实现递归函数。 3、通过变换能将一些递归转化为非递归,从而迭代求出结果。后两种方法在时空复杂度上均有较大改善,但其适用范围有限。,递归小结,算法设计与分析 递归与分治,32,算法设计与分析 递归与分治,2.2 分治(Divide and Conquer) 基本思想,Divide-and-Conquer(P)if ( |P|=n0) Adhoc(P); 直接求解问题 Pdivide P into smal

27、ler subinstances P1 ,P2,. ,Pk;for (i = 1;i = k; i+)yi=Divide-and-Conquer(Pi);return Merge( yl ,., yk); 将p1,p2,pk的解y1,y2,yk 合并成p的解,问 题 的 规 模,阈值,算法一般模式,将规模为N的问题分解为k个规模较小的子问题,使这些子问题相互独立可分别求解,再将k个子问题的解合并成原问题的解.如子问题的规模仍很大,则反复分解直到问题小到可直接求解为止. 在分治法中,子问题的解法通常与原问题相同,自然导致递归过程.,应用当中,通常将问题分解为k个(k=2)大小相等的子问题.,例

28、题 1-1,33,算法设计与分析 递归与分治,设问题P(n)分解成k个规模为n/m的子问题,阀值n0=1,求解P(1)的 时间耗费为O(1).将P(n)分解及合并成P(n)的解的时间为f(n),则 分治法解规模为n的问题的最坏时间复杂性函数T(n)满足:,T(n)=,算法的时间复杂性,Divide-and-Conquer(P)if ( |P|=n0) Adhoc(P); divide P into smaller subinstances P1 ,P2,. ,Pk;for (i = 1;i = k; i+)yi=Divide-and-Conquer(Pi);return Merge( yl ,

29、., yk);,f(n),kT(n/m),T(1)=O(1) T(n)=kT(n/m)+f(n),解得:,适用问题,大数相乘,矩阵乘法,快速富立叶变换, 棋盘覆盖,排序,选择 等.,O(1),34,T(1)=1 T(n)=2T(n/2)+2nT(n)=2 2T(n/22)+2*n/2 + 2n = 22T(n/22)+2*2n = 222T(n/23)+2n/22+ 2*2n =23T(n/23)+ 3*2n = = 2hT(n/2h)+ h*2n, 当h=log2n, 即2h=n时, =nT(1)+ 2nlog2n= n+ 2nlog2n=O(nlog2n),当k=m=2,f(n)=2n 时

30、,验证此公式:,35,算法设计与分析 递归与分治,2.4 大整数的乘法,设计一个有效的算法,可以进行两个n位大整数的乘法运算,小学的方法:O(n2) 效率太低 分治法:,X = Y = X = a 2n/2 + b Y = c 2n/2 + d XY = ac 2n + (ad+bc) 2n/2 + bd,a,b,c,d,复杂度分析T(n)=O(n2) 没有改进,36,算法设计与分析 递归与分治,2.4 大整数的乘法,XY = ac 2n + (ad+bc) 2n/2 + bd 为了降低时间复杂度,必须减少乘法的次数。 XY = ac 2n + (a-c)(b-d)+ac+bd) 2n/2 +

31、 bd XY = ac 2n + (a+c)(b+d)-ac-bd) 2n/2 + bd,细节问题:两个XY的复杂度都是O(nlog3),但考虑到a+c,b+d可能得到m+1位的结果,使问题的规模变大,故不选择第2种方案。,复杂度分析T(n)=O(nlog3) =O(n1.59)较大的改进,算法设计与分析 递归与分治,2.4 大整数的乘法,更快的方法,如果将大整数分成更多段,用更复杂的方式把它们组合起来,将有可能得到更优的算法。最终的,这个思想导致了快速傅利叶变换(Fast Fourier Transform)的产生。该方法也可以看作是一个复杂的分治算法。,算法设计与分析 递归与分治, S=S

32、IGN(X)*SIGN(Y);X:=ABS(X);Y:=ABS(Y);if n=l thenif (X=1) and (Y=1) then return(S)else return(0)else A:=X的左边n/2位;B:=X的右边n/2位;C:=Y的左边n/2位;D:=Y的右边n/2位;m1:=MULT(A,C,n/2);m2:=MULT(A-B,D-C,n/2);m3:=MULT(B,D,n/2);S:=S*(m1*2n+(m1+m2+m3)*2n/2+m3);return (S), X,Y为2个小于2n的二进制整数,返回结果为X和Y的乘积XY,function MULT(X,Y,n),

33、大数相乘的分治递归算法,二进制大整数乘法同样可应用于十进制大整数的乘法,存放XY的符号,存放三个乘积,算法,Strassen矩阵乘法,A和B的乘积矩阵C中的元素Ci,j定义为:,若依此定义来计算A和B的乘积矩阵C,则每计算C的一个元素Cij,需要做n次乘法和n-1次加法。因此,算出矩阵C的 个元素所需的计算时间为O(n3),传统方法:O(n3),Strassen矩阵乘法分治法,使用与上例类似的技术,将矩阵A,B和C中每一矩阵都分块成4个大小相等的子矩阵。由此可将方程C=AB重写为:,由此可得:,复杂度分析T(n)=O(n3),Strassen矩阵乘法,为了降低时间复杂度,必须减少乘法的次数。,

34、复杂度分析T(n)=O(nlog7) =O(n2.81)较大的改进,验证:C22 = M5+M1-M3-M7= (A11+A22)(B11+B22) +A11 (B12-B21)-(A21+A22) B11 - (A11-A21)(B11+B12)=A11B11+A11B22+A22B11+A22B22+A11B12-A11B22- A21B11 - A22B11 - A11B11- A11B12+A21B11+A21B12=A21B12+A22B22,算法设计与分析,procedure STRASSEN(n,A,B,C); if n=2 then MATRIX_MULTIPLY(A,B,C)

35、else 将矩阵A和B分块;STRASSEN( n/2,A11,B12-B22,M1);STRASSEN( n/2,A11+A12,B22,M2);STRASSEN( n/2,A21+A22,B11,M3);STRASSEN( n/2,A22,B21-B11,M4);STRASSEN( n/2,A11+A22,B11+B22,M5)STRASSEN( n/2,A12-A22,B21+B22,M6);STRASSEN( n/2,A11+A21,B11+B12,M7),C:=,矩阵相乘Strassen算法,T(n)=,T(2)= O(1) T(n)= 7T(n/2)+18(n/2)2,得: T(n

36、)=O(nlog7)=O(n2.81),分析:,算法,/18次小矩阵相加,Strassen矩阵乘法,更快的方法?,Hopcroft和Kerr已经证明(1971),计算2个矩阵的乘积,7次乘法是必要的。因此,要想进一步改进矩阵乘法的时间复杂性,就不能再基于计算22矩阵的7次乘法这样的方法了。或许应当研究或矩阵的更好算法。在Strassen之后又有许多算法改进了矩阵乘法的计算时间复杂性。目前最好的计算时间上界是 O(n2.376)是否能找到O(n2)的算法?,44,问题陈述:在一个2k2k个方格组成的棋盘中,恰有一方格残缺 残缺方格的位置有22k种。故对任何k0,残缺棋盘有22k种. 要求用L型骨

37、牌覆盖残缺棋盘上的所有方格且任何2个L型 骨牌不得重叠覆盖。,2k 2k 的棋盘覆盖中,用到的骨牌数为(4k-1)/3,2.6 棋盘覆盖,算法设计与分析 递归与分治,45,分治算法: 当k0时,将2k 2k棋盘分割为4个2k-1 2k-1子棋盘,残缺方格必位于4个子棋盘之一其余3个子棋盘中无残缺方格 为此将剩余3棋盘转化为残缺 棋盘. 用一个L型骨牌覆盖这 3个较小棋盘的结合处.,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的残缺方格,原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种 分割,直至棋盘简化为1 1棋盘.,算法分析:设T(k)为覆盖2k 2k残缺棋盘的时间, 当k=0时覆

38、盖它需要常数时间O(1) 当k0时,测试哪个子棋盘残缺以及形成3个残缺子棋盘需要O(1), 覆盖4个残缺子棋盘需四次递归调用,共需时间4T(k-1) ,T(k)=,O(1) 4T(k-1)+ O(1),得: T(k)=(4k),与所需骨 牌数同阶,算法设计与分析 递归与分治,算法设计与分析,void ChessBoard(int tr, int tc, int dr, int dc, int size) if (size=1) return;/tr, tc : Corner row & column no./dr,dc :特殊方格位置int t=tile+,/ L型骨牌号s=size2; /

39、分割棋盘/覆盖左上角子棋盘if (dr tr +s & dc tc +s)/特殊方格在此棋盘中ChessBoard(tr,tc,dr,dc,s);else/此棋盘中无特殊方格/用t号L型骨牌覆盖右下角Boardtr+s-1tc+s-1=t;/覆盖其余方格Chessboard(tr,tc,tr+s-1,tc+s-l,s);,(tr, tc),(dr, dc),size,(tr, tc),(dr, dc),size,算法设计与分析,/覆盖右上角子棋盘if (dr = tc +s)/特殊方格在此棋盘中ChessBoard(tr,tc +s ,dr,dc,s);else/此棋盘中无特殊方格/用t号骨牌

40、覆盖左下角Boardtr+s-1tc+s=t;/覆盖其余方格Chessboard(tr,tc+s,tr+s-1,tc+s,s); ,void outputBoard( int size) for int i=0 ;isize ;i+)for int j=0 ;jsize ;j+);coutsetw(5)board ij;coutendl ;,48,2.7 合并(merge)排序,算法思路:若n为1,算法终止;否则,将n个待排元素分割成k(k=2)个大致相等子集合A,B,对每一个子集合分别递归排序,再将排好序的子集归并为一个集合.,算法设计与分析 递归与分治,初始序列a 8 4 5 6 2 1

41、7 3 归并到b 4 8 5 6 1 2 3 7 复制到a 4 8 5 6 1 2 3 7 归并到b 4 5 6 8 1 2 3 7 复制到a 4 5 6 8 1 2 3 7 归并到b 1 2 3 4 5 6 7 8 复制到a 1 2 3 4 5 6 7 8,归并 4,5,6,8 1,2,3,7 从两个序列的头部开始归并: 4与1比较,1被移到结果序列;4与2比较,2被移入结果序列 4与3比较,3被放入结果序列;4和7比较,4被放入结果序列, 5和7比较.,,例如,二路归并,问题:将n个元素排成非递减顺序。,49,temlplate void MergeSort(Type a, int lef

42、t, int right) if (1eft right) /至少有2个元素int i = (left + right ) /2; /取中点MergeSort(a, 1eft, i);MergeSort(a, i+1, right);Merge(a, b, 1eft, i, right);/从a合并到数组bcopy(a, b, left, right);/复制回数组a ,T(n)=,d n=1 T(n)= 2T(n/2)+cn,得: T(n)=(nlogn),分析:,算法设计与分析 递归与分治 合并排序,算法如下,template void merge(T C, T d ,int l, int

43、 m , int r) /把cl:m,cm,r归并到dl,rint: i=l, /第段的游标j=m+1, /第二段的游标k=l; /结果的游标/只要段中存在i和j,则不断进行归并while (im) for (int q=j; q=r;q+) /前段已完dk+=cq;else for(int q=i ;q=m;q+) /后段已完dk+=cq;,50,2.8 快速排序,算法思路:对于输入a p: r ,按以下三个步骤进行排序: (1)分解:取a中的一个元素为支点(pivot) 将ap: r 划分成3段:ap: q-1, aq , a q+1:r, 使得 a p:q-1中任一元素aq, aq+1:

44、 r中任一元素 aq; 下标q 在划分过程中确定。 (2)递归求解:递归调用快速排序法分别对ap:q-1和aq+1:r 排序。 (3)合并:合并a p:q-1, aq , a q+1:r 为ap:r,算法设计与分析 递归与分治,a1:8=8, 4, 1, 7, 11, 5, 6, 9, 取元素8作为支点,例如,分解: aq=8; ap: q-1=4, 1, 7, 5, 6; aq+1:r=11,9; q=6,排序: ap:q-1=1, 4, 5, 6, 7; a q+1:r=9, 11。,合并:把ap:q-1中的元素放在支点元素8之前,aq+1:r中的元素放在支点元素之后,结果1, 4, 5,

45、 6, 7, 8, 9, 11,51,快速排序算法,template void QuickSort(Type a, int p, int r) if(pr)int q=Partition(a, p, r)QuickSort(a, p, q-1); /对左半段排序QuickSort(a, q+1, r); /对右半段排序,template int Partition(Type a ,int p , int r ) int i=p; j=r+1;type x=ap;/将=x的元素交换到左边区域/将 x);if (i=j ) break;swap(ai,aj); ap = aj;a j = x;return j ,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报