第2章_递归与分治策略

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
– 将求出的小规模的问题的解合并为一个更大规模的问 题的解,自底向上逐步求出原来问题的解。
2019/9/17
算法设计与分析
25
原问题 的规模是n
子问题1 的规模是n/2
子问题2 的规模是n/2
子问题1的解
子问题2的解
原问题的解
2019/9/17
算法设计与分析
26
问题(N个输入)
合 子问题1 并 解
• •
m=2时,A(n,2)=2n。 m=3时,类似的可以推出
2 2...2
n
• m=4时,A(n,4)的增长速度非常快,以至于没
有合适的数学式子来表示这一函数。
2019/9/17
算法设计与分析
9
举例2-6:Hanoi塔问题
• 问题定义:设a, b,c是3个塔座。开始时,在塔座a上有一 叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。 各圆盘从小到大编号为1,2,…,n,现要求将塔座a上的这一叠 圆盘移到塔座b上,并仍按同样顺序叠置。
15
需要先完成:Hanoi(2,a,b,c);
三阶Ha该n工oi作塔又问可题分解成:① Hanoi(1,a,c,b);②
MOVE(a,2,c);③ Hanoi(1,b,a,c)。
完成Hanoi(1,b,a,c); 工作等价于MOVE(b,1,c)。
1
3
2
塔座a
塔座b Hanoi(2,a,塔b,c座) c
MOVE(a,2,c);③ Hanoi(1,b,a,c)。
完成MOVE(a,2,c)。
3
1
2
塔座a
塔座b
塔座c
• 分析:完成Hanoi(3,a,c,b)的工作可以分解成如下 三个步骤:Hanoi(2,a,b,c)、MOVE(a,3,b)和 Hanoi(2,c,a,b)。
2019/9/17
算法设计与分析
说明:边界条件与递归方程是递归函数的两个要素,
递归函数只有具备了这两个要素,才能在有限次计
算后得出结果。
2019/9/17
算法设计与分析
4
递归函数的内部执行过程
递归函数内部执行过程如下:
(1)运行开始时,为递归调用建立一个工作栈,其结 构包括实参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的实参和局 部变量的当前值以及调用后的返回地址压栈;
子问题1
子问题2 … 子问题K 子问题2 … 子问题k
相同类型
• 由于分治法要求分解成同类子问题,并允许不断分 解,使问题规模逐步减小,最终可用已知的方法求 解足够小的问题。
问题1:什么是递归?
• 直接或间接地调用自身的算法称为递归算法,用 函数自身给出定义的函数称为递归函数。
• 举例:输出n个自然数。
Print_1( int n ) 非递归算法 Print_2( int n )
递归算法
{ int i;
{ if(n==0) return;
for(i=1; i<=n; i++)
• 如果最原始的问题为n阶Hanoi塔问题,且表示为 Hanoi( n, a, c, b )
• 则步骤2与步骤4为n-1阶Hanoi塔问题分别表示为:
Hanoi( n-1, a, b, c )
Hanoi( n-1, c, a, b ) 其中第一个参数表示问题的阶数,第二、三、四个 参数分别表示起始柱、中间柱与目的柱。 • 将a塔座上的n号圆盘移到b塔座上
18446744073709551615/31556952=584554049253.85 5年 这表明移完这些金片需要5845亿年以上。 真的过了5845亿年,不说太阳系和银河系,至少地 球上的一切生命,连同梵塔、庙宇等,都早已经灰 飞烟灭。
2019/9/17
算法设计与分析
22
• 另外一个印度传说:舍罕王打算奖赏国际象棋 的发明人──宰相西萨·班·达依尔。国王问他想 要什么,他对国王说:“陛下,请您在这张棋 盘的第1个小格里赏给我一粒麦子,在第2个小 格里给2粒,第3个小格给4粒,以后每一小格都 比前一小格加一倍。请您把这样摆满棋盘上所 有64格的麦粒,都赏给您的仆人吧!”国王觉 得这个要求太容易满足了,就命令给他这些麦
Move( a, n, b )
2019/9/17
算法设计与分析
19
• 补充举例之算法:求解n阶Hanoi塔问题。
Hanoi( n, a, c, b )
IF n=1 THEN move(a, 1, b)
ELSE
{Hanoi( n-1, a, b, c )
move( a, n, b )
Hanoi( n-1, c, a, b )
第2章 递归与分治策略
第2章 递归与分治策略
学习要点
• 理解递归的概念 • 掌握设计有效算法的分治策略:分治法的基本思
想 • 通过范例学习分治策略的算法分析及设计技巧
– 二分搜索技术、大整数的乘法、Strassen矩阵乘法 – 合并排序和快速排序
2019/9/17
算法设计与分析
2
2.1 递归的概念
(3)每次递归调用结束后,将栈顶元素出栈,使相应 的实参和局部变量恢复为调用前的值,然后转向返回地 址指定的位置继续执行
举例2-2:Fibonacci数列
• 无穷数列1, 1, 2, 3, 5, 8, 13, 21, 34, 55,…,被称
为Fibonacci数列。 • 它可以递归定义为:
边界条件
单的问题(二阶Hanoi塔问题);
• 然后将这些较简单的每一个问题(二阶Hanoi塔问题)再归 结为更简单的问题,直到最简单的问题(一阶Hanoi塔问题)
为止。
2019/9/17
算法设计与分析
17
再分析:n阶Hanoi塔问题
• 求解的步骤: 1. 如果n=1,则可直接将这一个圆盘移动到目的柱
上,过程结束。如果n>1,则进行步骤2。
} RETURN
T(n)=2n-1
1 T(n) 2T(n 1) 1
n1 n1
2019/9/17
算法设计与分析
20
汉诺塔的由来
• 印度的古老传说:在世界中心贝拿勒斯(在印 度北部)的圣庙里,一块黄铜板上插着三根宝 石针。印度教的主神梵天在创造世界的时候, 在其中一根针上从下到上地穿好了由大到小的 64片金片,这就是所谓的汉诺塔。不论白天黑 夜,总有一个僧侣在按照下面的法则移动这些 金片:一次只移动一片,不管在哪根针上,小 片必须在大片上面。僧侣们预言,当所有的金 片都从梵天穿好的那根针上移到另外一根针上 时,世界就将在一声霹雳中消灭,而梵塔、庙 宇和众生也都将同归于尽。
• 分析:完成Hanoi(3,a,c,b)的工完作成可! 以分解成如
下三个步骤:Hanoi(2,a,b,c)、MOVE(a,3,b)和
Hanoi(2,c,a,b)。
2019/9/17
算法设计与分析
16
总结:三阶Hanoi塔问题
1 2 3
塔座a
塔座b
塔座c
• 将一个复杂的问题(三阶Hanoi塔问题)归结为若干个较简
• 在移动圆盘时应遵守以下移动规则:
(1)每次只能移动1个圆盘;
(2)任何时刻都不允许将较大的 圆盘压在较小的圆盘之上;
(3)在满足移动规则1和2的前提
下,可将圆盘移至a,b,c中任一塔
座上。
2019/9/17
算法设计与分析
10
特例:三阶Hanoi塔需问要题完成:Hanoi(3,a,c,b);
其中,参数1表示一共需要 移动几个圆盘;参数2表示 起始塔座;参数3表示中间 塔座;参数4表示目的塔座。
1 2 3
塔座a
2019/9/17
塔座b
算法设计与分析
塔座c
12
分析
• 递归思路: – 当n=1时,只要将编号1的盘子从A移到B即 可; – 当n>1时,要以C为辅助,此时设法将n-1个 较小的盘子从A移到C,将剩下的最大盘子 从A移到B,最后,再设法将n-1个较小的盘 子从C移到B。这样,n个盘子的移动就可以 分解为两次n-1个盘子的移动。
2. 设法将起始柱的上面n-1个圆盘(编号1到n-1)按
移动原则移动到中间柱上。
3. 将起始柱上的最后一个圆盘(编号为n)移到目
的柱上。
4. 设法将中间柱上的n-1圆盘按移动原则移到目的 柱上。
2019/9/17
算法设计与分析
18
• 步骤2与步骤4实际上还是Hanoi塔问题,只不过其 规模小一些而已。
2019/9/17
算法设计与分析
7
举例2-3:Ackerman函数(了解)
• 当一个函数及它的一个变量是由函数自身定义时, 称这个函数是双递归函数。
• Ackerman函数A(n, m)定义如下,n, m是两个独 立的整变量,其中n, m均≥0:

A1,0 2

A0, m 1

粒。当人们把一袋一袋的麦子搬来开始计数时
,国王才发现:就是把全印度甚至全世界的麦 粒全拿来,也满足不了那位宰相的要求。
2019/9/17
算法设计与分析
23
递归小结
• 优点:结构清晰,可读性强,而且容易用数学 归纳法来证明算法的正确性,因此它为设计算 法、调试程序带来很大方便。
• 缺点:递归算法的运行效率较低,无论是耗费 的计算时间还是占用的存储空间都比非递归算 法要多。
2019/9/17
算法设计与分析
21
• 汉诺塔问题需要耗费的时间为
当n=64时,
f(n)=2n-1
f(64)= 264-1=18446744073709551615
假如每秒钟一次,共需多长时间呢?一个平年365 天有 31536000 秒,闰年366天有31622400秒,平均 每年31556952秒,计算一下,
• 分析:完成Hanoi(3,a,c,b)的工作可以分解成如下 三个步骤:Hanoi(2,a,b,c)、MOVE(a,3,b)和 Hanoi(2,c,a,b)。
2019/9/17
算法设计与分析
14
需要先完成:Hanoi(2,a,b,c);
三阶Ha该n工oi作塔又问可题分解成:① Hanoi(1,a,c,b);②

1
n0
F
n


1
n1
F n 1 F n 2 n 1
递归方程
int Fibonacci(int n) { if (n<=1) return 1;
return Fibonacci(n-1)+Fibonacci(n-2); }
2019/9/17
算法设计与分析
6
分析
1
2
3
塔座a
塔座b
塔座c
• 分析:起始塔座a上有三个圆盘,所以该问题 被称为三阶Hanoi塔问题。
2019/9/17
算法解法:将A、B、C、A构成一个顺时针循环。在移动 盘子的过程中,若是奇数次移动,则将最小的盘子移到顺 时针方向的下一塔座上;若是偶数次移动,则保持最小盘 子不动,而在其他两个塔座之间,将较小的盘子移到另一 塔座上。
else
printf(“%d”,i);
{ Print_2(n-1);
printf(“\n”); 201r9e/9t/1u7 rn; }
printf(“%d”,n); }
算法设计与分析return; }
3
举例2-1:阶乘函数
• 可递归定义为:
1
n0
n! n(n 1)! n 0
• 其中: • n=0时,n!=1为边界条件(基础步) • n>0时,n!=n(n-1)!为递归方程(归纳步)
201772算法设计与分析26子问题1的规模是n2子问题1的解子问题2的解子问题2的规模是n2原问题的解原问题的规模是n201772算法设计与分析27问题n个输入子问题1子问题2子问题k子问题1子问题2子问题k由于分治法要求分解成同类子问题并允许不断分解使问题规模逐步减小最终可用已知的方法求解足够小的问题
• 解决方法:在递归算法中消除递归调用,使其
转化为非递归算法。
2019/9/17
算法设计与分析
24
2.2 分治法的基本思想
• 分治法的基本思想: – 将一个规模为n的问题分解为k个规模较小的子问题,
这些子问题互相独立且与原问题相同。
– 对这k个子问题分别求解。如果子问题的规模仍然不够 小,则再划分为k个子问题,如此递归的进行下去,直 到问题规模足够小,很容易求出其解为止。
2019/9/17
算法设计与分析
13
需要先完成:Hanoi(2,a,b,c);
三阶Ha该n工oi作塔又问可题分解成:① Hanoi(1,a,c,b);②
MOVE(a,2,c);③ Hanoi(1,b,a,c)。
完成Hanoi(1,a,c,b);
工作等价于MOVE(a,1,b)。
2
3
1
塔座a
塔座b
塔座c
• 以上两例中的函数也可以用如下非递归方式定 义:
n!= 1×2×3×…×(n-1)×n
F(n)
1 5


1
2
5
n1


1
2
5 n1


• 但是并非所有递归函数都能用非递归方式定义, 例如Ackerman函数就不能用非递归方式定义。
An,0 n 2
An, m AAn 1, m, m 1
m0 n2 n, m 1
2019/9/17
算法设计与分析
8
分析
• A(n,m)的自变量m的每一个值都定义了一个单 变量函数:
• m=0时,A(n,0)=n+2。
• m=1时,A(n,1)=2n。
相关文档
最新文档