算法设计与分析习题第二章分治与递归
第2章 递归与分治_作业答案讲解

具体执行过程:求最大值
0 1 2 3 4 5 6 7 8 9 10 11 12 13 24 -13 29 113 87 65 -9 36 14 76 44 83 67 5 0 1 2 3 4 5 6 24 -13 29 113 87 65 -9 0 1 2 3 24 -13 29 113 0 1 24 -13 2 3 29 113 4 5 6 87 65 -9 7 8 9 10 11 12 13 36 14 76 44 83 67 5 7 8 9 10 36 14 76 44 7 8 36 14 7 36 9 10 76 44 11 12 13 83 67 5 11 12 83 67 11 83 12 67 13 5
课后练习
• 练习2:分析如下时间函数的复杂度,并说明 原因。 1. 利用递归树说明以下时间函数的复杂度:
O(1) T ( n) 3T ( n ) O( n) 4 n1 n1
2. 利用主定理说明以下时间函数的复杂度:
T(n) = 16T(n/4) + n
T(n) = T(3n/7) + 1
课后练习
• 练习1:给定数组a[0:n-1], 1. 试设计一个分治法算法,找出a[0:n-1]中元素最 大值和最小值; 2. 写出该算法时间函数T(n)的递推关系式; 3. 分析该算法的时间复杂度和空间复杂度。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 24 -13 29 113 87 65 -9 36 14 76 44 83 67 5
• 递归公式:
– 设n个元素的集合可以划分为F(n,m)个不同的由 m个非空子集组成的集合。 F(n,m) = 1, when n=0, n=m, n=1, or m=1 F(n,m) = 0, when n<m 否则 F(n,m)=F(n-1,m-1)+m*F(n-1,m)
第2章_递归与分治策略

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

计算F(n-1)所需 乘法次数 计算F(n-1) ×n所需 乘法次数
初始条件(initial condition):停止递归调用的条件 T(0) = 0
• Conquer: 一个划分确定后,A[s]的位置便确定,再 对两个子数组递归地划分 • Combine: 原地排序in-place sort,无需合并
Quicksort(A[l…r]) if l < r s = Partition(A[l…r]) Quicksort(A[l…s-1]) Quicksort(A[s+1…r]) Partition(A[l…r]) p = A[l] //选择第一个元素作为划分基准 i = l; j = r + 1 repeat repeat i = i + 1 until A[i] ≥ p //left-to-right scan repeat j = j - 1 until A[j] ≤ p //right-to-left scan swap(A[i], A[j]) until i ≥ j swap(A[i], A[j]) //undo last swap when i ≥ j swap(A[l], A[j]) return j
二分搜索(Binary Search)
• 给定已按升序排好序的n个元素A[0…n-1],现要在 这n个元素中找出一特定元素k。
– 蛮力算法:遍历、 Tworst(n) =O(n) – 分治法是否适用?
• • • •
算法设计与分析实验指导1_分治与递归

《算法设计与分析》实验指导实验一分治与递归一、实验目的:1. 理解递归的概念。
2. 掌握设计有效算法的分治策略。
3. 掌握C++面向对象编程方法。
二、实验指导1. 分治法的总体思想求解一个复杂问题可以将其分解成若干个子问题,子问题还可以进一步分解成更小的问题,直到分解所得的小问题是一些基本问题,并且其求解方法是已知的,可以直接求解为止。
分治法作为一种算法设计策略,要求分解所得的子问题是同类问题,并要求原问题的解可以通过组合子问题的解来获取。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效的算法。
2. 分治法的基本步骤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(y1,...,yk); //将各子问题的解合并为原问题的解}3. C++类定义例class Complex{public:Complex( ):real(0),imag(0) {} //构造函数Complex(double r,double i):real(r),imag(i) {} //构造函数Complex operator + (Complex c2); //重载“+”运算符operator double( ) //重载类型转换运算符{return real;}friend ostream& operator << (ostream&,Complex&); //重载流插入运算符“<<”private:double real;double imag;};三、实验内容及要求:在程序中创建一个学生对象数组并初始化数据,完成如下编程任务。
[工学]算法设计与分析第二章
![[工学]算法设计与分析第二章](https://img.taocdn.com/s3/m/c3999dcd5ef7ba0d4a733b29.png)
递归复杂性的一般形式
• 一般的,递归复杂性可描述为递归方程: 1 n=1 f(n) = af(n ~ b) + D(n) n>1 • 其中,a是子问题个数, ~表示递减方式, b是递减步长, D(n)是合成子问题的开销。 • 通常,递归元的递减方式~有两种: 分治法 1、除法,即n / b,的形式; 递推法 2、减法,即n – b,的形式。
第二章
递归与分治
2018/11/20
计算机算法设计与分析
1
递归的思想
• 递归(Recursion)就是通过把复杂问题分解为 较简单的同一问题来求解。 • 递归求解问题的方法通常有两步: • 第一步是考虑最简单的情况下该问题如何 求解。 • 第二步是考虑该问题的较复杂情况是如何 由较简单的所构成的。 • 由此得出该问题求解的方法。
2018/11/20 计算机算法设计与分析 28
分治法的基本思想
• 将一个规模为n的问题分解为a个规模较小的 子问题,这些子问题互相独立并且与原问题 相同。 • 递归地求解这些子问题问题。 • 然后将各个子问题的解合并在一起,从而得 到原问题的解。 • 影响其时间复杂性的因素是子问题的个数和 合并开销函数,其中较大者起主要作用。
A B C
2018/11/20
计算机算法设计与分析
4
Hanoi塔问题
• 让我们先考虑最简单的情况: • 1、若没有盘子(n=0),自然不需要做任何事情。 • 2、若只有一个盘子,也很容易。直接把它移到B 盘即可。
• 不妨设操作Move(X, Y) 将X柱上的一个盘子(最 顶上的)移到Y柱上。
A B C
GCD(x, y) = y, x, GCD(x – y, y), GCD(x, y – x), x=0 y = 0 最简单 x y 的情况 x < y 有两种
计算机专业课《算法》_第二章 递归与分治策略

“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
初始条件与递归方程是递归函数的二个要素
大学_计算机算法设计与分析第4版(王晓东著)课后答案下载

计算机算法设计与分析第4版(王晓东著)课后答
案下载
计算机算法设计与分析第4版内容简介
第1章算法概述
1.1 算法与程序
1.2 算法复杂性分析
1.3 NP完全性理论
算法分析题1
算法实现题1
第2章递归与分治策略
2.1 递归的概念
2.2 分治法的基本思想
2.3 二分搜索技术
2.4 大整数的乘法
2.5 Strassen矩阵乘法
2.6 棋盘覆盖
2.7 合并排序
2.8 快速排序
2.9 线性时间选择
2.10 最接近点对问题
第3章动态规划
第4章贪心算法
第5章回溯法
第6章分支限界法
第7章随机化算法
第8章线性规划与网络流
附录A C++概要
参考文献
计算机算法设计与分析第4版目录
本书是普通高等教育“十一五”__规划教材和国家精品课程教材。
全书以算法设计策略为知识单元,系统介绍计算机算法的设计方法与分析技巧。
主要内容包括:算法概述、递归与分治策略、动态规划、贪心算法、回溯法、分支限界法、__化算法、线性规划与网络流等。
书中既涉及经典与实用算法及实例分析,又包括算法热点领域追踪。
为突出教材的`可读性和可用性,章首增加了学习要点提示,章末配有难易适度的算法分析题和算法实现题;配套出版了《计算机算法设计与分析习题解答(第2版)》;并免费提供电子课件和教学服务。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
7
2.7 按2.2.4节的描述,编写从二叉树中删除一个结点 的C语言程序 二叉树节点删除有三种情况: (1)*p是叶子(即它的孩子数为0):无须连接*p的子树, 只需将*p的双亲*parent中指向*p的指针域置空即可。 (2)*p只有一个孩子*child:只需将*child和*p的双亲直接 连接后,即可删去*p。注意:*p既可能是*parent的左孩 子也可能是其右孩子,而*child可能是*p的左孩子或右孩 子,故共有4种状态。 (3)*p有两个孩子:先令q=p,将被删结点的地址保存在q 中;然后找*q的中序后继*p,并在查找过程中仍用parent 记住*p的双亲位置。*q的中序后继*p一定是 *q的右子树 中最左下的结点,它无左子树。因此,可以将删去*q的 操作转换为删去的*p的操作,即在释放结点*p之前将其 数据复制到*q中,就相当于删去了*q.
2010-12-28 14
2.12 编写针对数组的归并排序程序。
void combine_sort( int a[], int s, int n ) //a[]为数组 { int k,b,c,m; int *r = new int[n]; if ( n>1 ) { k = n/2; combine_sort( a, s ,k ); //递归调用 combine_sort( a, s+k, n-k ); m = 0; b = s; c = s+k;
2 4 6 5 = 24 34 AB = 5 7 3 6 51 67
2010-12-28 17
2010-12-28
4
2.4 试写出求二叉树中序遍历序列的递归程序。 void walk (T_Node *p) { if ( p == NULL )return; walk( p->left); printf( p->data ); walk( p->right); } for the other example: void walk (T_Node *p, int *visit) { if(p){ if(walk( p->left)) if(visit( p->data )) if(walk( p->right))return ok; }else return ok; }
2010-12-28
10
Void Balance(BSTree &T) { lc=T->lchild; //lc指向*T的左子数根节点 rd=lc->rchild; //rd指向*T的左孩子的右子数根 T->bf=lc->bf=EH; //修改*T及其左孩子的平衡因子 rd->bf=EH; L.Rotate(T->lchild); //对*T的左子树作左旋平衡处理 R.Rotate(T); //对*T作右旋平衡处理 }
2010-12-28 5
2.5 针对图2.1(b)的二叉排序树,若查找的命中率 为100%,即不考虑查找的目标值不在树中的情况,则 平均需要多少次元素值的比较? 查找处于第k层的元素需要比较k次,对于图2.1(b), 总的比较次数为1×1+2×2+3×3+4×5=34,平均 次数34/11=3.1次。 11 4 3 1
2010-12-28
12
2.11 编写针对链表的快速排序程序。
需要保存指针信息。下面给出双向链表的快速排序算法 void fast_sort( Sdata *a, Sdata *f, Sdata *t ) { Sdata *i,*j,k,p; i = f; j = t; if ( t->lnext != f ) { k = a->data; //用于比较的基准数值 i = f; j = t; p = -1; while ( j != i )
2010-12-#43;k) && (c<s+n) ) //比较 比较 { if ( a[b] < a[c] ) r[m++] = a[b++]; else r[m++] = a[c++]; } if ( b == s+k ) for ( b=c; b<s+n; b++) r[m++] = a[b]; else for ( c=b; c<s+k; c++) r[m++] = a[c]; for ( m=0; m<n; m++) a[s++] = r[m]; } delete r; }
算法设计与分析习题
第二章 分治与递归
2010-12-28
1
2.1 对于顺序查找算法,分析目标值存在于数组中的 概率p趋于0的含义,这种情况下平均查找次数有什么 样的变化?当p趋于1时呢? 见教材P12。平均比较次数为 n - p(n-1)/2。 p趋于0,平均次数趋于n;p趋于1时,平均次数趋于 (n+1)/2。(求极限)
2010-12-28
13 6 17 9 14 19
6
5
2.6 向一棵空二叉树中依次插入如下元素值:8,9, 10,2,1,5,3,6,4,7,11,12,要求每插入一 个元素后的二叉树都是二叉排序树,画出每次插入元 素后的二叉排序树。 8 9 2 10 1 5 3 4 6 7 11 12
2010-12-28
2010-12-28 13
if ( p == 1 ) {
//从链表前面向后寻找比基准值大的数 从链表前面向后寻找比基准值大的数
while ( (j != i) && (i->data <= k) ) i = i->rnext; j->data = i->data; p = -1; } else { //从链表最后向前寻找比基准值小的数 从链表最后向前寻找比基准值小的数 while ( (j != i) && (j->data >= k) ) j = j->lnext; i->data = j->data; p = 1; } i->data = k; fast-sort( a, f, i->lnext ); //递归 递归 fast-sort( a, i->rnext, t ); } }
2010-12-28 8
2.8 针对平衡 的二叉排序树LR型失衡的情况,写出调整使之恢 复平衡的算法。 2 A C 0
B
-1 0 C B 0 A 0
A为最下部的失衡结点。
2010-12-28
9
破坏平衡的原因是由于在A的左子女(L)的右子树(R) 中插入结点,使A的平衡因子由-1变为-2而失去平 衡。 调整规则∶ a、 设C为A的左子女的右子女,将A的孙子结点C提升 为新二叉树的根; b、 原C的父结点B连同其左子树向左下旋转成为新根 C的左子树,原C的左子树成为B的右子树; c、 原根A连同其右子树向右下旋转成为新根C的右子 树,原C的右子树成为A的左子树。
2010-12-28
11
2.10 用快速排序法对如下的数据进行排序:45,23, 65,57,18,2,90,84,12,76。说明第一遍扫描的 具体过程。
45 45,23,65,57,18,2,90,84,12,76 12,23,65,57,18,2,90,84,45,76 12,23,65,57,18,2,90,84,45,76 12,23,45,57,18,2,90,84,65,76 12,23,45,57,18,2,90,84,65,76 12,23,2,57,18,45,90,84,65,76 12,23,2,57,18,45,90,84,65,76 12,23,2,45,18,57,90,84,65,76 12,23,2,45,18,57,90,84,65,76 12,23,2,18,45,57,90,84,65,76
2010-12-28 16
2.13 应用分治策略完成下面的整数乘法计算: 2348×3825。 套用公式(书上26) 2348 = 23*102 + 48, 3825 = 38*102 + 25 结果为:8981100
2.14 应用Strassen算法完成下面的矩阵乘法运算。 套用公式(书上28)
2010-12-28
2
2.2 对于折半查找算法,分析目标值存在与数组 中的概率p对算法的时间复杂度的影响。 见教材P12。平均比较次数为log2n。 平均次数与p关系不大,趋向于log2n。
2010-12-28
3
2.3 在一个由10个元素构成的数组中,用折半查找法 查各个位置上元素分别需要进行多少次元素值的比较? 数组元素 0 1 2 3 4 5 6 7 8 9 分别对应的比较次数 3 2 3 4 1 3 4 2 3 4