递归与分治法1

合集下载

递归与分治算法心得

递归与分治算法心得

递归与分治算法心得
递归与分治算法都是常用的算法思想,可以很好地解决复杂问题。

递归算法是通过将问题分解为相同或相似的子问题来解决整个问题,然后再逐步合并回原问题的过程。

递归算法通常需要明确边界条件,以确保递归能够正确地停止。

分治算法是将问题分解成若干个相同或相似的子问题,递归地解决这些子问题,然后合并这些子问题的解来解决原始问题。

通常,分治算法可以高效地解决问题,但需要注意分解问题的方式和合并子问题的解的过程。

在实际应用中,递归和分治算法可以相互结合,以解决更加复杂的问题。

例如,可以使用分治算法来将问题分解成多个子问题,然后使用递归算法来解决这些子问题。

此外,还可以在递归算法中使用分治算法来对子问题进行分解和合并。

总而言之,递归与分治算法都是非常有用的算法思想,可以在许多领域中得到应用。

但是,在实际使用时,需要仔细考虑问题的性质和算法的复杂度,以确保算法的正确性和效率。

- 1 -。

递归与分治算法心得

递归与分治算法心得

递归与分治算法心得
递归与分治算法是算法设计中常见的两种方法,它们在解决问题时都采用了“分而治之”的思想,将问题分解成更小的子问题,然后通过递归调用或者合并子问题的解来得到原问题的解。

通过我的学习和实践,我深刻认识到了递归与分治算法的重要性和优势。

首先,递归算法可以使问题的描述更加简单明了。

通过将问题转化为自身的子问题,我们可以建立起更为简洁优美的数学模型。

其次,递归算法可以使问题的解决过程更加自然。

在递归过程中,我们可以利用已知的子问题解决同类问题,实现代码的复用和模块化。

此外,递归算法还可以解决一些重要的数学问题,如斐波那契数列和二分查找等。

分治算法则更加注重问题的分解和合并。

它将问题划分成若干个规模相同或相近的子问题,然后将子问题的解合并起来得到原问题的解。

这种方法在解决某些复杂问题时具有很大的优势。

例如,在排序算法中,归并排序采用了分治算法的思想,将待排序的序列分成两个长度相等的子序列,然后递归地对子序列排序,最后将子序列合并成有序序列。

这种算法具有较高的稳定性和灵活性,常常被应用于海量数据的排序任务中。

总之,递归与分治算法是算法设计中不可或缺的两种方法。

在解决问题时,我们应该根据具体情况选择合适的算法,并在实践中不断探索、总结和优化。

只有这样,我们才能更好地应对日益复杂多变的计算机科学挑战。

递归和分治法

递归和分治法

递归和分治法摘要:1.递归和分治法的定义2.递归和分治法的区别3.递归和分治法的应用实例4.递归和分治法的优缺点正文:递归和分治法是计算机科学中常用的两种算法设计技巧。

它们在解决问题时都采用了将问题分解成更小子问题的思路,但在具体实现上却有所不同。

下面,我们来详细了解一下递归和分治法。

1.递归和分治法的定义递归法是指在算法中调用自身来解决问题的方法。

递归函数在执行过程中,会将原问题分解成规模更小的相似子问题,然后通过调用自身的方式,解决这些子问题,最后将子问题的解合并,得到原问题的解。

分治法是指将一个大问题分解成若干个规模较小的相似子问题,然后分别解决这些子问题,最后将子问题的解合并,得到原问题的解。

分治法在解决问题时,通常需要设计一个主函数(master function)和一个子函数(subfunction)。

主函数负责将问题分解,子函数负责解决子问题。

2.递归和分治法的区别递归法和分治法在解决问题时都采用了将问题分解成更小子问题的思路,但它们在实现上存在以下区别:(1)函数调用方式不同:递归法是通过调用自身来解决问题,而分治法是通过调用不同的子函数来解决问题。

(2)递归法必须有递归出口,即必须有一个基线条件,而分治法不一定需要。

3.递归和分治法的应用实例递归法应用广泛,例如斐波那契数列、汉诺塔问题、八皇后问题等。

分治法也有很多实际应用,例如快速排序、归并排序、大整数乘法等。

4.递归和分治法的优缺点递归法的优点是代码简单易懂,但缺点是容易产生大量的重复计算,导致时间复杂度较高。

分治法的优点是时间复杂度较低,但缺点是代码实现相对复杂,需要设计主函数和子函数。

总之,递归和分治法都是解决问题的有效方法,具体应用需要根据问题的特点来选择。

算法设计与分析课件--分治法-线性时间选择

算法设计与分析课件--分治法-线性时间选择
9
2.5 线性时间选择
这样找到的m*划分是否能达到O(n)的时间复杂度? |A| = |D| = 2r, |B| = |C| = 3r +2,n = 10r +5. |A| + |D| + |C| = 7r + 2 = 7(n-5)/10 +2 = 7n/10 -1.5 < 7n/10 表明子问题的规模不超过原问题的7/10(d)。
T(n) = T(cn) + T(dn) + tn
6
2.5 线性时间选择
Select(S, k) Input: n个数的数组S,正整数k
T(n) = T(cn) + T(dn) + tn
Output: S中的第k个小元素
1. 将S划分成5个元素一组,共[n/5]个组;
2. 每组寻找一个中位数,把这些中位数放到集合M中;
寻找一个分割点m*, 使得左边子表S1中的元素都小于m*, 右子表 S2中的元素都大于m*。 如果寻找m*的时间复杂度达到O(nlogn), 那就不如直接使用排序 算法了。 如果直接寻找m*, 时间复杂度是O(n). 假设选择算法的时间复杂度为T(n), 递归调用这个算法在S的一 个真子集M上寻找m*,应该使用T(cn)时间,这里c是小于1的常数, 反映了M的规模与S相比缩小许多。
✓ 不妨假设n是5的倍数,且n/5是奇数,即n/5 = 2r+1. 于是: |A| = |D| = 2r, |B| = |C| = 3r +2,n = 10r +5.
✓ 如果A和D中的元素都小于m*,那么把它们的元素都加入到S1, S1对应规约后子问题的上限。 类似的,若A和D中的元素都 大于m*, 则把他们的元素都加 入到S2,S2对应规约后子问题 的上限。

分治法和动态规划

分治法和动态规划

分治法和动态规划⼀.分治法 1.分治法的设计思路是,将⼀个难以直接解决的⼤问题,分割成⼀些规模⽐较⼩的相同的⼩问题,以便各个击破,分⽽治之。

2.分治法所能解决的问题的⼀般有以下的特征: (1)该问题的规模缩⼩到⼀定的程度就可以容易解决(绝⼤多数的问题都满⾜) (2)该问题是可以分解为若⼲个规模较⼩的相同的问题,即改问题具有最优⼦结构性质(前提,也是绝⼤多数的问题都满⾜的) (3)利⽤该问题分解出的字问题的解可以合并该问题(关键) (4)该问题分解出来的各个⼦问题是相互独⽴的(分治法的效率) (如果具备⼀⼆条,但不具备第三条,可以考虑使⽤贪⼼算法或动态规划) 3.分治法的基本步骤: (1)分解:将原问题分解为若⼲个规模较⼩、互相独⽴、与原问题形式相同的⼦问题。

(2)解决:若⼲问题规模较⼩⽽容易被解决则直接解,否则递归地解各个⼦问题 (3)合并:将各个⼦⽂题的解合并成原问题的解 (记住不是所有的分治法逗逼简单的蛮⼒法简单) 4.分治法的时间性能的与直接计算最⼩问题的时间、合并⼦⽂题解的时间以及⼦问题的个数有关: c n=1T(n)= aT(n/b)+cn^k n>1(其中a,b.c.k都是常数。

这个递推描述了⼤⼩为n的原问题分解为若⼲⼤⼩为n/b的⼦问题,其中a个⼦问题需求求解,⽽cn^k是合并各个⼦问题的解所需要的⼯作量) 当⼦问题的规模之和⼩于原问题的规模时,算法的时间复杂度可达到0(n).⼆.动态规划1.简单的说就是在解决多阶决策的过程中动态的选择最优的过程的⽅法就是动态规划。

2.与分治法的区别:⼀般来说⼦问题不是互相独⽴的,可以理解为是分治法的⼀种改进,不需要求解已有解的⼦问题(已有解的⼦问题⽤表来记录)3.适⽤条件:(1)最优化原理(最优⼦结构):⼀个最优策略的⼦策略总是最优的---->局部最优,整体最优(2)⽆后效性:每个状态都是过去历史的⼀个完整的总结(3)⼦问题的重叠性:⾼效性(最优⼦结构:当问题的最优解包含其⼦问题的最优解时,称该问题具有最有⼦结构;重叠⼦问题是⼀个递归解决⽅案⾥包含的⼦问题虽然很多,但不同⼦问题很少。

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)实验目的:掌握递归与分治法的基本思想和应用,学会设计和实现递归算法和分治算法,能够分析和评价算法的时间复杂度和空间复杂度。

实验内容:1.递归算法的设计与实现3.算法的时间复杂度和空间复杂度分析实验步骤:1)递归定义:一个函数或过程,在其定义或实现中,直接或间接地调用自身的方法,被成为递归。

递归算法是一种控制结构,它包含了解决问题的基础情境,也包含了递归处理的情境。

2)递归特点:递归算法具有以下特点:①依赖于递归问题的部分解被划分为若干较小的部分。

②问题的规模可以通过递推式递减,最终递归终止。

③当问题的规模足够小时,可以直接求解。

3)递归实现步骤:①确定函数的定义②确定递归终止条件③确定递归调用的过程4)经典实例:斐波那契数列递推式:f(n) = f(n-1) + f(n-2)int fib(int n) {if (n <= 0)return 0;else}5)优化递归算法:避免重复计算例如,上述斐波那契数列的递归算法会重复计算一些中间结果,影响效率。

可以使用动态规划技术,将算法改为非递归形式。

int f1 = 0, f2 = 1;for (int i = 2; i <= n; i++) {f1 = f2;使用循环避免递归,重复计算可以大大减少,提高效率。

1)分治算法的定义:将原问题分解成若干个规模较小且类似的子问题,递归求解子问题,然后合并各子问题得到原问题的解。

2)分治算法流程:②将问题分解成若干个规模较小的子问题。

③递归地解决各子问题。

④将各子问题的解合并成原问题的解。

3)分治算法实例:归并排序归并排序是一种基于分治思想的经典排序算法。

排序流程:②分别对各子数组递归进行归并排序。

③将已经排序好的各子数组合并成最终的排序结果。

实现源代码:void mergeSort(int* arr, int left, int right) {if (left >= right)while (i <= mid && j <= right)temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];temp[k++] = arr[i++];1) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。

计算机专业课《算法》_第二章 递归与分治策略

计算机专业课《算法》_第二章 递归与分治策略

“Hanoi 塔”问题演示 a 初始 a 步骤1 a
c
b
c
“Hanoi 塔”问题程序
void hanoi(int n,a,b,c)
{ if n == 1 move( 1, a, b );
else { hanoi( n-1, a, c, b );
move(n, a, b ); hanoi( n-1, c,b, a) ;
• 递归优点:结构清晰,可读性强
• 递归缺点:递归算法的运行效率较低,无论是耗 费的计算时间还是占用的存储空间都比非递归算 法要多。
整数划分问题的递归关系q(n,m)
如设p(n)为正整数n的划分数,则难以找到递归关系 • q(n,m):正整数n的不同的划分中,最大加数不 大于m的划分个数个数 q(n,m)=
1 q(n,n) 1+q(n,n-1) q(n,m-1)+q(n-m,m) n=1, m=1 n<m n=m n>m>1
递归函数举例(5)
学习要点
理解递归的概念。 掌握设计有效算法的分治策略。
通过典型范例,学习分治策略设计技巧。
2.1 递归的概念
• 递归算法:一个直接或间接地调用自身的算法 • 递归方程:对于递归算法,一般可把时间代 价表示为一个递归方程 • 递归函数:使用函数自身给出定义的函数 • 解递归方程最常用的方法是进行递归扩展
递归函数举例(1)
• 阶乘函数 n !=
1 n(n-1)! n=1 n>1
• Fibonacci数列
1 n=0
F(n)=
1 F(n-1)+F(n-2)
n=1 n>1
初始条件与递归方程是递归函数的二个要素

算法之2章递归与分治

算法之2章递归与分治

算法分析(第二章):递归与分治法一、递归的概念知识再现:等比数列求和公式:1、定义:直接或间接地调用自身的算法称为递归算法。

用函数自身给出定义的函数称为递归函数。

2、与分治法的关系:由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。

在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。

这自然导致递归过程的产生。

分治与递归经常同时应用在算法设计之中,并由此产生许多高效算法。

3、递推方程:(1)定义:设序列01,....na a a简记为{na},把n a与某些个()ia i n<联系起来的等式叫做关于该序列的递推方程。

(2)求解:给定关于序列{n a}的递推方程和若干初值,计算n a。

4、应用:阶乘函数、Fibonacci数列、Hanoi塔问题、插入排序5、优缺点:优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。

缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

二、递归算法改进:1、迭代法:(1)不断用递推方程的右部替代左部(2)每一次替换,随着n的降低在和式中多出一项(3)直到出现初值以后停止迭代(4)将初值代入并对和式求和(5)可用数学归纳法验证解的正确性2、举例:-----------Hanoi塔算法----------- ---------------插入排序算法----------- ()2(1)1(1)1T n T nT=−+=()(1)1W n W n nW=−+−(1)=021n-23()2(1)12[2(2)1]12(2)21...2++2 (121)n n n T n T n T n T n T −−=−+=−++=−++==++=−(1)2 ()(1)1((n-2)+11)1(2)(2)(1)...(1)12...(2)(1)(1)/2W n W n n W n n W n n n W n n n n =−+−=−−+−=−+−+−==++++−+−=−3、换元迭代:(1)将对n 的递推式换成对其他变元k 的递推式 (2)对k 进行迭代(3)将解(关于k 的函数)转换成关于n 的函数4、举例:---------------二分归并排序---------------()2(/2)1W n W n n W =+−(1)=0(1)换元:假设2kn =,递推方程如下()2(/2)1W n W n n W =+−(1)=0 → 1(2)2(2)21k k k W W W−=+−(0)=0(2)迭代求解:12122222321332133212()2(2)212(2(2)21)212(2)22212(2)2*2212(2(2)21)2212(2)222212(2)3*2221...2(0)*2(22...21)22k k k k k k k k k k k k k k k k k k k k k k k k W n W W W W W W W W k k −−−−−−−+−+−−−=+−=+−+−=+−+−=+−−=+−+−−=+−+−−=+−−−==+−++++=−1log 1n n n +=−+(3)解的正确性—归纳验证: 证明递推方程的解是()(1)/2W n n n =−()(1)1W n W n n W =−+−(1)=0,(n 1)=n +n=n(n-1)/2+n =n[(n-1)/2+1]=n(n+1)/2n W W +方法:数学归纳法证 n=1,W(1)=1*(1-1)/2=0假设对于解满足方程,则()---------------快速排序--------------------->>>平均工作量:假设首元素排好序在每个位置是等概率的112()()()(1)0n i T n T i O n n T −==+=∑ >>>对于高阶方程应该先化简,然后迭代(1)差消化简:利用两个方程相减,将右边的项尽可能消去,以达到降阶的目的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


解题思路
Fn 1 Fn 2 Fn 1 n 3; n 1,2.
递归程序实现 F(n) if n<=1 then return 1 else return F(n-1)+F(n-2) 非递归程序实现 F(n) F0 ← 1 F1 ← 1 for i ← 1 to n do F2 ← F1+F0 F0 ← F1 F1 ← F2 return F2
随机快速排序(改进)
RandomizedPartition(A,p,r) i← Random(p,r) exchange A[p]↔A[i] return Partition(A,p,r)
归并排序问题
该问题是将n 个元素排成非递减顺序。 算法描述 若n为1,算法终止;否则,将这一元素 集合分割成两个或更多个子集合,对每 一个子集合分别排序,然后将排好序的 子集合归并为一个集合。

递归的应用

阶乘函数
n (n 1)! n 1; n! 1 n 0.
程序的实现 Factorial(n) if n=0 then return 1 else return n*Factorial(n-1)

Fibonacci数列

Fibonacci兔子问题描述 从某天开始把雄和雌各一的一对兔子放入养殖 场中,小兔经过一个月长大。长大后,每个月 它们都繁殖一对雄和雌各一的一对小兔,每对 新兔经过一个月长大。长大后,每对新兔也繁 殖一对雄和雌各一的一对小兔,如果每一对兔 子的繁殖按上面所说的方式,试问第n个月, 养殖场中有多少对兔子呢?
棋子移动问题

问题描述 有2n个棋子(n>3)排成一行,开始时白子 全部在左边,黑子全部在右边,要求把它 移成黑白相间的一行棋子。 移动规则: 每次必须移动相邻的2个棋子,颜色不限; 但是不能调换2个棋子的左右位臵。移动 必须跳过若干个棋子到左边或右边的空位 上去(不能平移)。
解题思路

考虑n=5的情况 if p < r then q← (p + r)/2 MergeSort(A,p,q) MergeSort(A, q + 1, r) Merge(A,p,q,r)
Merge(A, p, q, r) n1←q-p+1 n2←r - q create arrays L[1.. n1 + 1] and R[1 n2 + 1] for i←1 to n1 do L[i]←A[p+i-1] for j←1 to n2 do R[j]←A[q + j] L[n1+1]←∞ R[n2 + 1]←∞ i←1; j←1 for k ← p to r do if L[i] ≤ R[j] then A[k] ← L[i] i←i+1 else A[k] ← R[j] j←j+1
青蛙过河问题

问题描述
大小各不相同的一队青蛙站在河左岸的石墩 (记为A)上,要过到对岸的石墩(记为D)上 去。河心有几片荷叶(分别设为Y1 … Ym)和几 个石墩(分别设为S1 … Sn)。如下图

青蛙的站队和移动的方法规则如下: 1.每只青蛙只能站在荷叶、石墩或者比它大 一号的青蛙背上; 2.一只青蛙只有在背上没有其他青蛙时才能 从一个落脚点跳到另一个落脚点; 3.青蛙允许从A直接跳到河心的石墩、荷叶 和D上,允许从河心的石墩、荷叶跳到D上; 4.青蛙可以在河心的石墩、荷叶之间以及石 墩和荷叶之间来回跳动; 5.青蛙离开A后,到达D后,均不能再跳回。
if dr >= tr + s and dc < tc + s then TileBoard(tr+s, tc, dr, dc, s) else Board[tr + s][tc + s - 1] ← t TileBoard(tr+s, tc, tr+s, tc+s-1, s) if dr >= tr + s and dc >= tc + s then TileBoard(tr+s, tc+s, dr, dc, s) else Board[tr + s][tc + s] ← t TileBoard(tr+s, tc+s, tr+s, tc+s, s)
伪币问题的推广:二分搜索
问题描述 给定已经排好序的n个元素a[0..n-1],现要从 这n个元素中找出一特定元素。 求解思路 二分搜索算法的基本思想是将n个元素分成个 数大致相同的两半,取a[n/2]与x进行比较。 如果x=a[n/2]则找到x,算法中止。如果 x<a[n/2],则只要在数组a的左半部分继续搜 索x。如果x>a[n/2],则只需继续搜索数组a的 右半部分。
快速排序问题
该问题是将n 个元素排成非递减顺序。 解题思路 分解:将输入的序列A[p..r]划分成两个非空 子序列A[p..q-1]和A[q+1..r]。 递归求解:通过递归调用快速排序算法分别对 A[p..q-1]和A[q+1..r]进行排序。 合并:将从小到大已排序的A[p..q-1]和 A[q+1..r]合并使其按从小到大排序
Hanoi(n, A, B, C) if n=1 then move(1, A, C) else Hanoi(n-1, A, C, B) move(n, A, C) Hanoi(n-1, B, A, C)
排列问题

排列问题 设R={r1,r2,…,rn}是要进行排列的n个元 素,Ri =R-{ri }。集合R中元素的全排列 记为Perm(R)。 (ri)Perm(Ri)表示在全排 列Perm(Ri)的每一个排列前加上前缀ri得 到的排列。R的全排列可归纳定义如下: 当n=1时, Perm(R)=r1 当n>1时, Perm(R)由(r1)Perm(R1), (r2)Perm(R2),…,(rn)Perm(Rn)构成。
递归策略
递归算法:一个直接或间接的调用自身的 算法。它通常把一个大型复杂的问题层层 转化为一个与原问题相似的规模较小的问 题来求解,递归策略只需少量的程序就可 描述出解题过程所需要的多次重复计算, 大大地减少了程序的代码量。 递归程序:递归函数,递归过程 注意: (1) 递归就是在过程或函数里调用自身; (2) 在使用递增归策略时,必须有一个明 确的递归结束条件,称为递归出口。
MovetoSpace(k) c[sp] ← c[k] c[k] ←空格 c[sp+1] ← c[k+1] c[k+1] ←空格 sp ←k
自然数的拆分问题
问题描述 任何一个大于1的自然数n,总可以拆分成若干 个小于n的自然数之和。给定n,求n的所有拆 分。 例如n=4,可拆分为 4=1+3 4=1+1+2 4=1+1+1+1 4=2+2 解题思路

找伪币问题

给你一个装有16个硬币的袋子。16个硬 币中有一个是伪造的,并且那个伪造的 硬币比真的硬币要轻一些。你的任务是 找出这个伪造的硬币。为了帮助你完成 这一任务,将提供一台可用来比较两组 硬币重量的仪器,利用这台仪器,可以 知道两组硬币的重量是否相同。

算法描述 1)将16个硬币分成A、B两半; 2)将A放仪器的一边,B放另一边,如果A 袋轻,则表明伪币在A,解子问题A即可, 否则,解子问题B。

考虑n=3的情况

n=4的一个解
ChessMove(n) if n=4 then MovetoSpace(4) MovetoSpace(8) MovetoSpace(2) MovetoSpace(7) MovetoSpace(4) else MovetoSpace(n) MovetoSpace(2n-1) ChessMove(n-1)
例子
残缺棋盘问题
残缺棋盘是一个有2k×2k 个方格的棋盘,其中 恰有一个方格残缺。残缺棋盘的问题要求用L 型的格板覆盖残缺棋盘。在此覆盖中,两个三 格板不能重叠,三格板不能覆盖残缺方格,但 必须覆盖其他所有的方格。 图中给出k≤2时各种可能的残缺棋盘,其中残 缺的方格用阴影表示。注意当k= 0时,仅存在 一种可能的残缺棋盘。事实上,对于任意k, 恰好存在22k 种不同的残缺棋盘。

Hanoi塔问题

问题描述 有n个圆盘,半径各不相同,依半径从大到小 自下而上套在A柱上,另还有B、C两根空柱, 现要求将A柱上的n个圆盘全部搬到C柱上去且 每次只许搬动一个盘子,还必须始终保持每根 柱子上是小盘在上,大盘在下。试问: (1)要移动多少次才能把A柱上的n个圆盘移到 C柱上? (2)怎么个移动法?

程序实现
BinarySearch(x,a,n) left ← 0 right ← n-1 while left<=right do middle ←(left+right)/2 if x=a[middle] then return middle if x>a[middle] then left ← middle+1 else right ← middle-1 return -1

QuickSort(A,p,r) if p < r then q← Partition(A, p, r) QuickSort(A, p, q - 1) QuickSort(A, q + 1, r) QuickSort(A, 1, length[A])
划分程序
Partition(A, p, r) x ← A[r] i←p-1 for j ← p to r - 1 do if A[j] ≤ x then i ← i + 1 exchange A[i] ↔ A[j] exchange A[i + 1] ↔ A[r] return i + 1
相关文档
最新文档