计算机问题求解关于递归与分治法合

合集下载

计算机算法设计与分析第2章递归和分治策略

计算机算法设计与分析第2章递归和分治策略

, n>=1
2019/4/14
24
2.1 递归的概念
例3

Ackerman函数
A(n,m)的自变量m的每一个值都定义了一个单变量 函数(根据m的不同可得到基于n的不同函数!): m=2时,
A(n,2)=A(A(n-1,2),1)


n=0, A(0,2)=1 n=1, A(1,2)=A(A(0,2),1)= A(1,1)= 2 n>=2,A(n,2)=A(A(n-1,2),1)=2A(n-1,2) A(n,2)= 2^n , n>=0
A(1,0) 2 A(0, m) 1 A(n,0) n 2 A(n, m) A( A(n 1, m), m 1)
2019/4/14
m 0, n 1 m 0, n 0 m 0, n 2 m 1, n 1
21
2.1 递归的概念
2019/4/14 22
2.1 递归的概念
例3

Ackerman函数
A(n,m)的自变量m的每一个值都定义了一个单变量 函数(根据m的不同可得到基于n的不同函数!): m=0时,
n=0,

A(0,0)=1 n=1, A(1,0)=2 n>=2, A(n,0)=n+2
2019/4/14
23
2019/4/14
32
2.1 递归的概念
与原问题类型一致而其规模却不断缩小,最终使子 问题缩小到很容易直接求出其解。 这自然导致递归过程的产生。

分治与递归像一对孪生兄弟,经常同时应用在 算法设计之中,并由此产生许多高效算法。
14
2019/4/14

递归与分治策略解决最大字段和问题

递归与分治策略解决最大字段和问题

递归与分治策略---最大子段和问题1、问题的描述给定由n个整数组成的序列(a1,a2, …,an),求该序列形如的子段和的最大值。

分治算法就是将一个问题分解成若干个小问题,对若干个小问题分别求解,最后在合并起来。

最大子段问题可以分成三种情况1.数组a[1-n](即数组前1至n个元素) 的最大子段和a[1-n/2]的最大子段相同2数组a[1-n](即数组前1至n个元素) 的最大子段和a[n/2+1-n]的最大子段相同3.数组a[1-n]的最大子段和是由a[1-n/2]和a[n/2+1-n]结合而成,求解方法为则分别求出n/2 imax∑a[k] 和max ∑a[k] ,然后将两个值相加即得到此种情况下的数组最大子段和0<=i<=n/2 k=i n/2+1<=i<=n k=n/2最后分别求出三种情况的最大子段和,再比较三个子段和,最大的那个即为数组的最大字段和。

2、代码及注释#include <stdio.h>#include <stdlib.h>#include <time.h>#define MAX_N 20int max3(int, int, int);int maxSubArrayAns(int []);int maxSubArray(int [], int, int);int main(){int nums[MAX_N];//定义一个最大长度为20的数组int i;srand(time(0));//随机数产生器printf("array: \n");//产生MAX_N个随机数for( i = 0; i < MAX_N; i++){//随机数产生的规则nums[i] = (int)(rand() % (MAX_N * 2) - MAX_N);printf("%d\t", nums[i]);}printf("\n");//调用递归函数printf("The max subsequen sum is %d.\n", maxSubArrayAns(nums));return 0;}//求三个数中的最大值int max3(int a, int b, int c){if(a > b)return a > c ? a : c;elsereturn b > c ? b : c;}//采用分治策略int maxSubArray(int nums[], int left, int right){int maxLeftSum, maxRightSum;//左右边的最大和int maxLeftBorderSum, maxRightBorderSum;//含中间边界的左右部分最大和 int leftBorderSum, rightBorderSum;//含中间边界的左右部分当前和//递归到最后的基本情况if(left == right)if(nums[left] > 0)return nums[left];elsereturn 0;//递归求左右部分最大值int mid = (left + right) / 2, i;maxLeftSum = maxSubArray(nums, left, mid);maxRightSum = maxSubArray(nums, mid + 1, right);//求含中间边界的左部分的最大值maxLeftBorderSum = 0, leftBorderSum = 0;for(i = mid; i >= left; i--){leftBorderSum += nums[i];if(leftBorderSum > maxLeftBorderSum)maxLeftBorderSum = leftBorderSum;}//求含中间边界的右部分的最大值maxRightBorderSum = 0, rightBorderSum = 0;for(i = mid + 1; i <= right; i++){rightBorderSum += nums[i];if(rightBorderSum > maxRightBorderSum)maxRightBorderSum = rightBorderSum;}//返回三者中的最大值return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);}int maxSubArrayAns(int nums[]){return maxSubArray(nums, 0, MAX_N - 1);}3、运行结果4、结果分析在这个程序中采用生成随机数的方法,产生20个分布在0左右的数字。

递归与分治算法心得

递归与分治算法心得

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

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

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

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

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

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

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

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

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

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

- 1 -。

计算机算法分治和递归

计算机算法分治和递归

C12 = A11B12 + A12B22; C22 = A21B12 + A22B22
m
h
PROC. 2-waysort( r1, L, h, r2 ); IF L = h THEN r2[L] := r1[L] ELSE [ m := (L + h ) DIV 2; 2-waysort( r1, L, m, r3 ); 2-waysort( r1, m+1, h, r3 ); merge( r3, L, m, h, r2 ) ]
9
删除广义表中所有元素为x的原子结点 删除广义表中所有元素为 的原子结点 分析: 分析: 比较广义表和线性表的结构特点: 比较广义表和线性表的结构特点:
相似处:都是链表结构 相似处: 不同处: 广义表的数据元素可能还是个广义表; 不同处:1) 广义表的数据元素可能还是个广义表 2) 删除时,不仅要删除原子结点, 删除时,不仅要删除原子结点, 要删除原子结点 还需要删除相应的表结点。 还需要删除相应的表结点。
5
递归的终结状态是 递归的终结状态是,当前的问题可 终结状态 以直接求解,对原问题而言,则是已走 直接求解,对原问题而言, 到了求解的最后一步 最后一步。 到了求解的最后一步。 链表是可以如此求解的一个典型例子。 链表是可以如此求解的一个典型例子。 例如:编写“删除单链表中所有值为 例如 编写“删除单链表中所有值为x 的 编写 数据元素”的算法。 数据元素”的算法。
14
2. 实现递归函数,目前必须利用 实现递归函数 递归函数, “栈”。一个递归函数必定能改写为利 用栈实现的非递归函数;反之,一个用 用栈实现的非递归函数;反之, 栈实现的非递归函数可以改写为递归函 数。需要注意的是递归函数递归层次的 深度决定所需存储量的大小。 深度决定所需存储量的大小。

算法之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)差消化简:利用两个方程相减,将右边的项尽可能消去,以达到降阶的目的。

递归与分治ppt课件

递归与分治ppt课件
C三个柱子间移动。}
2023/10/8
计算机算法设计与分析
3
Hanoi塔问题的时间复杂性
n Hanoi塔问题的时间复杂性为O(2n)。 n 证明:对n归纳证明move(n) = 2n – 1。 n 归纳基础:当n = 1, move(1) = 1 = 21 – 1。 n 归纳假设:当n k, move(n) = 2n – 1。 n 归纳步骤:当n= k + 1,移动次数为
2、除法,即n / b,的形式
2023/11/4
计算机算法设计与分析
21
递归算法的时间复杂性
n 若~为减法,即n – b,则有:
T(n) = aT(n – b) + D(n)
= a(aT(n – 2b) + D(n – b)) + D(n) =
k–1
k–1
= akT(1) + ai D(n – ib) = ak + ai D(n – ib)
n q最(n简, m单)情{ 形1:(1) q(n, 1)=1, q(1, mn)==1 n或, mm≥1=;1 n 递q(iin归ff,((mnn关)<=系==1):1q1)||(|((+|nm2(,)qmm<(qn=–(1,n1=)n,)–+1n1)q))(=rrnee–1ttmuu+rr,nqnm(01n);;, nnn>–≤1m)m,>n1>1; n 产i生f (n的=新= 情1) 况|| (:n < m) return 1 + q(n, n–1); n (3r)eqtu(nr,nmq)(n=,qm(n–,1m) +–1q)(n+–qm(,nm–m);, m} ), n>m>1 n (整4)数q(nn的, m划)分= q数(nρ,(n),=nq<(nm, n。)。

递归与分治法1

递归与分治法1


解题思路
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个棋子的左右位臵。移动 必须跳过若干个棋子到左边或右边的空位 上去(不能平移)。

算法设计与分析——浅谈递归思想与分治策略

算法设计与分析——浅谈递归思想与分治策略
汉诺塔问题
(1) 若只有一个盘子,直接从柱子A移动到柱子C (2) 若有两个盘子,先将最上面一个盘子移动到B,再将底下的盘子移动 到C,再将B上的盘子移动到C (3) 若有三个盘子,先借助C将A最上面的两个盘子移动到B,将最大的盘 子移动到C,此时A为空,再借助A将B最上面的一个盘子移动到A,将B 剩余的一个盘子移动到C,再将A上的盘子移动到C …………… 以此类推,假设A上有n个盘子,先借助C将A上n-1个盘子移动到B,再 将第n个盘子移动到C,再借助A盘将B上的n-1个盘子移动到C. 由此可见,此中不断重复一个借助某个柱子将另外一个柱子上的最下面 的盘子移动到第三个柱子上的过程.
算法设计与分析——初章
结束了… 主要内容: 1. 算法的时间复杂度 2. 递归思想
递归定义 直接递归调用与间接递归调用 递归应用 递归算法举例---Hanoi
3.分治策略
分治策略描述 二分法(二分查找,二分插入) 快速排序 归并排序

{2,4,5,7 }
{1,2,3,6}
{1,2,2,3,4,5,6,7}
分治策略
归并排序
在上述序列中,将整个序列从中间分成两个子序列,{5,2, 4,7 }和{1,3,2,6},然后将两个子序列按照相同的规则继续划 分直至不能再分为止, {5}{2}{4}{7}{1} {3}{2}{6},然后将不能再分 的子序列排序,对相邻的两个子序列进行归并操作,归并的规则 是: (1)取出相邻两个子序列中最小的数相比较,将两个数添加到归 并后的序列中. (2)对两个子序列中剩余的元素重复(1)操作. (3)当某个子序列为空后,将另一个子序列中的元素直接添加到 序列末尾. (4)重复(1)操作.
递归思想
汉诺塔问题
Hanoi有四个参数,第一个参数表示盘子的数目,第二个参数表示源柱 子,第三个参数表示要借助的柱子,第四个参数表示目标柱子. if(n==1) move(chA, chC) else { Hanoi(chA, chC, chB);//借助C将A上除了最下面一个移动到B move(chA, chC) Hanoi(chB, chA, chC);//借助A将B上面的移动到C }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Part 1
Part 2
问题5:跨中点的部分如何计算?
非递归代价:常量
递归,理想状况下 问题规模是原来的 一半。 非递归代价: 线性
非递归代价: 常量
O(n log n)
矩阵乘法:似乎非得(n3)
1个n阶方阵相乘的问题 可以分解为8个n/2阶方 阵相乘的子问题。
仍然是立方复杂度
问题6:
决定上面的递归代价 比较大的原因是什么?
the sequence
i=0 i=1 i=2 j
in O(n2)
i=n-1
用分治法解最大子数组问题
Part 1 the sub with largest sum may be in: recursion Part 2
Part 1 or:
Part 2
The largest is the result
n
lo g 3 4
Total: (n2)
T(n)=aT(n/b)+f(n)
f(n) f(n )
a
f(n/b) f(n/b) f(n/b)
af(n/ b)
a
logbn f(n/b2) f(n/b2) f(n/b2) f(n/b2) f(n/b2) f(n/b2) f(n/b2) f(n/b2) f(n/b2) …… …… … T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1) … T(1) T(1) T(1)
问题3:
如何考虑分治算法的代价?
递归代价与非递归代价
导出递归式
两次递归,理想情 况下每次问题规模 是原来的一半。
非递归开销
cn log n
确实比插入 排序效率高。
n
这里似乎假设n是2的整次幂,在我们涉 及的大多数情况下,这不影响结果。
问题4:
书上的投资回报问题是怎样 被转化为最大子数组问题的?
n/2
T(n/2)
n/2
T(n/4)
n/4
T(n/4)
n/4
T(n/4)
n/4
T(n/4)
n/4
对应于 T(n)=T(n/2)+T(n/2)+n 的递归树
对应于分治法的递归树方程

divide-and-conquer:
T(n) = aT(n/b) + f(n)

After kth expansion:
问题7:
你能否描述Strassen 方法的基本思想?
复杂的组合为了减少一次乘法
诸Si只需通过加减法计算
这个算法曾经引起轰动
问题8:
你对于这个结果是否有感性认识?
问题9:
为什么降低子问题个数会导致 复杂度的阶下降?
递归树
T(size) T(n) n nonrecursive cost
T(n/2)
log ba n
a2 f (n/ b2)

Note: a
lo g n b
n
lo g a b
Total ?
Solving the Divide-and-Conquer

T(n)=aT(n/b)+f(n)作为一种典型的分治算法递归式:



Let base-cases occur at depth D(leaf), then n/bD=1, that is D=lg(n)/lg(b) Let the number of leaves of the tree be L, then L=aD, that is L=a(lg(n)/lg(b)). By a little algebra: L=nlg(a)/lg(b), lg(a)/lg(b)=1/16)n)2
……
…… c((1/16)n)2
3 cn 16
2
2
T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1)T(1)T(1) T(1) T(1)
log 43 n


Note:3
lo g n 4
lg a L b 2 2 lg n lg b
lg n lg b
lg n lg a lg b
log a b 2 n
lg a lg n lg b
因此,这个值决定了树的“胖”度。
Divide-and-Conquer: the Solution




The recursion tree has depth D=lg(n)/ lg(c), so there are about that many row-sums. The 0th row-sum is f(n), the nonrecursive cost of the root. logb a n The Dth row-sum is , assuming base cases cost 1, or ( ) in any event. The solution of divide-and-conquer equation is the non-recursive costs of all nodes in the tree, which is the sum of the row-sums.
k 1 n k i 1 n T ( n ) a T a f k i 1 b i b 1
T(n)=3T(n/4)+(n2)
cn2 cn2
3 cn 16
2
c(¼
n)2
c(¼ n)2
c(¼
n)2
log4n c((1/16)n)2 c((1/16)n)2 …… ……
Maximum subarray
简单的遍历所有可能的子序列
下面的过程遍历的顺序为: (0,0), (0,1), …, (0,n-1); (1,1), (1,2), …, (1,n-1), …… (n-2,n-2), (n-2, n-1), (n-1,n-1)
MaxSum = 0; for (i = 0; i < N; i++) { ThisSum = 0; for (j = i; j < N; j++) { ThisSum += A[j]; if (ThisSum > MaxSum) MaxSum = ThisSum; } } return MaxSum;
计算机问题求解 – 论题2-3 - 分治法与递归
2013年03月12日
Mergesort Revisited
问题1:
这个算法究竟是如何“排”序的?
5
2
4
7 Divide
1
3
2
6
conquer
5 2 4 7
1
3
2
6
Divide further, until…
问题2:
人的思维“分而治之” 如何变为算法策略的呢?
相关文档
最新文档