4 算法分析与设计 第四讲 分治法及相关实例分析(续)
算法设计与分析分治法

• 缺点:
– 需要线性的额外空间,体现在何处 – 虽然合并也可做到在位,但导致算法过于复杂,
16
4.2 快速排序
• 算法思路: 对于A 0.. n-1 ,按以下三个步骤进行排序:
• 1 分区:取A中的一个元素为支点 pivot 将A 0..n-1 划分成3段: A 0..s-1 , A s , A s+1..n-1 , 使得 A 0..s-1 中任一元素A s , A s+1..n-1 中任一元素 A s ; 下标s 在划分过 程中确定,
• 有了上面的中序遍历的过程,前序遍历也是类似的,在遍 历以前首先确定遍历的树是否为空,如果为空,则直接返 回;否则前序遍历的算法步骤如下: 1 访问输出根结点V的值; 2 对左子树L执行前序遍历算法, 3 对右子树R执行前序遍历算法,
1
分治法的基本思想
subproblem 1 of size n/2
a solution to subproblem 1
a problem of size n
subproblem 2 of size n/2
a solution to subproblem 2
a solution to the original problem
32
中序遍历 Inorder Traversal
• 二叉树的中序遍历算法比较简单,使用递归的策略,在遍 历以前首先确定遍历的树是否为空,如果为空,则直接返 回;否则中序遍历的算法步骤如下: 1 对左子树L执行中序遍历算法 2 访问输出根结点V的值, 3 对右子树R执行中序遍历算法,
33
算法设计与分析-第四章-分治算法

第四章分治算法§1. 算法基本思想考虑下面折半搜索算法程序4-1-1 折半搜索template<class T>int BinarySearch(T a[], const T& x, int n){//在数组a[0:n-1]中搜索x,数组中的元素满足a[0]<=a[1] //<= ···<=a[n-1]。
如果找到x,则返回所在位置(数组元素的下标),//否则返回–1int left=0; int right=n-1;while(left<=right){int middle=(left+right)/2;if(x==a[middle]) return middle;if(x>a[middle]) left=middle+1;else right=middle – 1;}return –1; //未找到x}while 的每次循环(最后一次除外)都将以减半的比例缩小搜索范围,所以,该循环在最坏的情况下需要执行)Θ次。
由于每次循环需耗时)1((log nΘ,因此在最坏情况下,总的时间复杂性为)Θ。
(log n折半搜索算法贯彻一个思想,即分治法。
当人们要解决一个输入规模,比如n,很大的问题时,往往会想到将该问题分解。
比如将这n个输入分成k个不同的子集。
如果能得到k个不同的可独立求解的子问题,而且在求出这些子问题的解之后,还可以找到适当的方法把它们的解合并成整个问题的解,那么复杂的难以解决的问题就可以得到解决。
这种将整个问题分解成若干个小问题来处理的方法称为分治法。
一般来说,被分解出来的子问题应与原问题具有相同的类型,这样便于采用递归算法。
如果得到的子问题相对来说还较大,则再用分治法,直到产生出不用再分解就可求解的子问题为止。
人们考虑和使用较多的是k=2的情形,即将整个问题二分。
以下用A[1:n]来表示n个输入,用DanC(p,q)表示处理输入为A[p:q]情况的问题。
算法设计与分析 第四次课

KRUSKAL(G, w) _Disjoint Set
1. 2. 3. 4. 5. 6. 7. 8. 9. A← for each vertex v ∈ V [G] do MAKE-SET (v) sort the edges of E by nondecreasing weight w for each edge (u, v) ∈ E, in order by nondecreasing weight do if FIND-SET (u) ≠ FIND-SET (v) then A ← A ∪ { (u, v)} UNION(u, v) Return A
Algorithm MERGE
输入:数组A[1..m],索引1≤p ≤ q <r ≤ m,两个子数组A[p..q]和A[q+1..r] 别非降序排列 输出:合并A[p..q]和A[q+1..r]的数组A[p..r] B[p..r]为辅助数组 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. s←p; t←q+1; k←p; while s ≤ q and t ≤ r If A[s] ≤ A[t] then B[k] ← A[s] s ← s+1 else B[k] ← A[t] t ← t+1 end if k ←k+1 end while If s=q+1 then B[k..r] ← A[t..r] else B[k..r] ← A[s..q] end if A[p..r] ← B[p..r] 分
合并排序效率
• 假定n 是2的幂,即n = 2k, k 是大于等于0的 整数。 • 如果n = 1, 则算法不执行任何元素的比较 • 如果n > 1, 则执行了步骤2到步骤5,根据函 数C 的定义(n元素需比较次数),执行步骤3 和步骤4需要的元素比较次数都为C(n/2)。 • 合并两个子数组所需的元素比较次数在n/2 与n – 1 之间
算法设计与分析-分治法

3.2.1 归并排序
算法3.1——归并排序
void MergeSort(int r[ ], int r1[ ], int s, int t) {
if (s= =t) r1[s]=r[s]; //只有一个元素,直接赋值 else {
m=(s+t)/2; Mergesort(r, r1, s, m); //归并排序前半个子序列 Mergesort(r, r1, m+1, t); //归并排序后半个子序列 Merge(r1, r, s, m, t); //合并两个已排序的子序列 } }
A、B、C、D 四个区域
Ø想法
Ø 用二维数组data[N][N]表示N×N的方阵,观察方阵中数
字的规律,可以从外层向里层填数。 Ø 设变量size表示方阵的大小,则初始时size = N,填完一
层则size = size - 2;
Ø想法
Ø 设变量begin表示每一层的起始位置,变量i和j分别表示
MergeSort(r,r1,1,1) r1[1]=r[1]
Merge(r1,r,0,0,1)
MergeSort(r,r1,2,3)
MergeSort(r,r1,2,2) r1[2]=r[2]
MergeSort(r,r1,3,3) r1[3]=r[3]
Merge(r1,r,2,2,3)
Merge(r1,r,0,1,3)
• 分治思想 • 归并排序 • 快速排序 • 折半查找 • 选择问题 • 最大子段和问题 • 棋盘覆盖问题 • 循环赛日程安排问题
3.1 基本思想 3.2 排序问题中的分治算法 3.3 查找问题中的分治算法 3.4 组合问题中的分治算法 3.5 典型问题的C++程序(略)
算法设计与分析的一些实例分析

实验一递归与分治策略一、实验目的:熟练掌握递归与分治策略的思想并应用其解决实际问题。
二、递归与分治策略思想基本思想:将要求解的较大规模的问题分割成k个更小规模的子问题。
对这k个子问题分别求解。
如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
实验题目(1-2):找出从自然数1,2,…,n中任取r个数的所有组合。
算法思想:当组合的第一个数字选定时,其后的数字是从余下的m-1个数中取k-1数的组合。
这就将求m个数中取k个数的组合问题转化成求m-1个数中取k-1个数的组合问题。
设函数引入工作数组a[ ]存放求出的组合,约定函数将确定的k个数字组合的第一个数字放在a[k]中,当一个组合求出后,才将a[ ]中的一个组合输出。
第一个数可以是m、m-1、……、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未确定组合的其余元素,继续递归去确定;或已确定了组合的全部元素,输出这个组合。
问题描述:找出从自然数1、2、……、n中任取r个数的所有组合。
例如n=5,r=3的所有组合为:(1)5、4、3 (2)5、4、2 (3)5、4、1(4)5、3、2 (5)5、3、1 (6)5、2、1(7)4、3、2 (8)4、3、1 (9)4、2、1(10)3、2、1分析所列的10个组合,可以采用这样的递归思想来考虑求组合函数的算法。
设函数为void find(int m,int k)为找出从自然数1、2、……、m中任取k个数的所有组合。
当组合的第一个数字选定时,其后的数字是从余下的m-1个数中取k-1数的组合。
这就将求m个数中取k 个数的组合问题转化成求m-1个数中取k-1个数的组合问题。
设函数引入工作数组a[ ]存放求出的组合的数字,约定函数将确定的k个数字组合的第一个数字放在a[k]中,当一个组合求出后,才将a[ ]中的一个组合输出。
第一个数可以是m、m-1、……、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未去顶组合的其余元素,继续递归去确定;或因已确定了组合的全部元素,输出这个组合。
大学_计算机算法设计与分析第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
最好情况
O(nlogn),即当数据已经有序时的时间复杂度 。
平均情况
O(nlogn),根据概率计算得到的平均时间复杂 度。
3
最坏情况
O(n^2),即当数据已经逆序时的时间复杂度。
合并的结果应该是原问题的 解
完善细节
01
对合并的结果进行检验和调整
02
对算法进行优化,提高运行效 率
03
处理特殊情况或异常情况
03
分治法的优化策略
动态规划优化
总结词
通过将问题拆分为子问题,并存储子问题 的解,以避免重复计算,提高算法效率。
VS
详细描述
动态规划是一种常见的优化技术,其基本 思想是将问题拆分为一系列子问题,并将 子问题的解存储起来,以便在需要时可以 重复使用。通过这种方式,可以避免重复 计算相同的子问题,从而提高算法效率。 此外,动态规划通常用于优化递归问题, 如背包问题、最长公共子序列等。
但是,如果每个子问题的规模很大, 则空间复杂度也可能很大。
THANKS
谢谢您的观看
02
分治法的基本步骤
分解问题
将原问题划分成若干个子问题 每个子问题都包含原问题的一部分 子问题的规模尽可能小,以便更容易解决
解决子问题
对每个子问题进行递归求解 子问题的解可以构成原问题的解的一部分 对每个子问题进行归纳,得出原问题的解
合并子问题的解
将子问题的解合并成一个整 体
合并的过程中需要处理数据 结构或数据类型的一致性
算法设计与分析讲义分治 法
4算法第四章分治法

变型算法BINSRCH1
将BINSRCH的case语句用if语句来替换。
procedure BINSRCH(A, procedure n, x, j) BINSRCH1(A, n, x, j) integer low, high, mid, integer j, n; low, high, mid, j, n; low←1; high←n low←1; high←n+1 //high总比可能的取值大1 while low≤high do while low<high-1 do ← mid← mid (low+high)/2 (low+high)/2 case if x<A(mid) //在循环中只比较一次 :x<A(mid): high←mid-1 then high←mid :x>A(mid): low←mid+1 else low←mid //x>=A(mid) : else: j←mid; return; endif 最好、最坏和平均 endcase repeat repeat if x=A(low) then j←low //x出现 情况时间对于成功 j←0 else j←0 //x不出现 和不成功的检索都 end BINSRCH end BINSRCH1
//取中间值 //寻找前一半 //寻找后一半 //检索成功, 结束
//检索失败
二分检索实例
设在A(1:9)中顺序放了以下9个元素:
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9]
-15 -6 检索x=9
0
7
9
①
23
low 1
54
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
12
最近点对问题
合并子问题小结
找出以L为中心线,宽度为2������������的带状区域 获得带状区域中排序后的点集Y’ 对Y’中的每个点,检查其后面的7个点,计算距离并 更新最近点对的距离
13
最近点对问题
递归的出口 点数较少时的情形
Y Y Y
直接计算
直接计算
d=∞
X X X
只有一个点
1 length[YL] ← length[YR] ← 0 2 for i ← 1 to length[Y] 3 do if Y[i] ∈ PL 4 then length[YL] ← length[YL] + 1 5 YL[length[YL]] ← Y[i] 6 else length[YR] ← length[YR] + 1 7 YR[length[YR]] ← Y[i]
10
最近点对问题
合并子问题
关注以直线L为中心,宽度为2������������的垂直带状区域 看是否可以找到一个点对的距离������������’<������������
11
最近点对问题
合并子问题 考察带状区域中的点
对于带状区域中的每个点p,算法试图找出距离p在 ������������单位以内的点,如果距离������������’<������������,则更新当前的最近 点对距离 如果带状区域中的点是按y坐标升序排列的,对于 每个点p,只需要检查p之后的7个点即可
最小元:第1个顺序统计量 最大元:第n个顺序统计量 i 中位数:= (n + 1) / 2
18
寻找顺序统计量问题
如下假设:
集合由n个数值不同的元素组成 在此假设下的结论可以推广到有重复数值的情形
问题描述:
输入:一个包含n个不同数的集合A和一个数i 输出:元素x,x大于A中其它的i-1个元素
示例,n个元素
30
寻找顺序统计量问题
示例, n个元素分为n/5+1组
31
寻找顺序统计量问题
示例,寻找 n/5+1组中每一组的中位数
32
寻找顺序统计量问题
示例,递归调用SELECT找出n/5的中位 数x
33
寻找顺序统计量问题
至少有一半组( n/5 /2= n/10组)的 中位数小于或等于x
分治法
当n=2时,一次比较就可以找出两个数据元素的最 大元和最小元 当n>2时,可以把n个数据元素分为大致相等的两半 求数组最大元、最小元的算法下界
3n / 2 − 2
4
最近点对问题
对于平面上给定的N个点,给出距离最近 的两个点
Brute force法:把所有点对逐一检查一遍
26
寻找顺序统计量问题
最坏情况线性时间 基本思想:保证对数组的划分是好的划分
27
寻找顺序统计量问题
SELECT的步骤
1.将输入数组的n个元素分为n/5+1组,其中n/5 组每组5个元素,余下的一组由剩下的n mod 5个元 素组成; 2.寻找这n/5+1组中每一组的中位数(先对每组中 的元素进行插入排序,然后从排序后的序列中选出 中位数); 3.对第二步中找出的n/5+1组中位数,递归调用 SELECT以找到其中位数x;
8
最近点对问题
解决
分别寻找PL和PR中的最近点对及距离,设其找到的 最近点对的距离分别是δL和 δR 置δ=min(δL, δR)
9
最近点对问题
合并
对于从PL和PR求得的δL和δR,如何合并? 可能一:最近点对就是某次递归调用找出的距离为 ������������的点对 可能二:最近点对是由PL 中的一个点和PR中的一个 点组成的点对
• T(n)=Θ(n2)
分治策略
• 如何分解? • 如何合并?
5
一维的最近点对问题
n个点退化为n个实数,最近点对即为这n 个实数中相差最小的两个实数 分治法求解
分解:用各点坐标的中位数m作为分割点,分成两 个点集 求解:在两个点集上分别找出其最接近点对{p1,p2} 和{q1,q2} 合并:整个点集的最近点对或者是{p1,p2},或者是 {q1,q2},或者是某个{p3,q3},其中p3和q3分属两 个点集
28
寻找顺序统计量问题
SELECT的步骤 续
4.PARTITION,按中位数x对输入数组进行划分,x 为第k小元素; 5.如果i=k,则返回x; 否则,如果i<k,则在低区递归调用SELECT寻找第i 小元素 否则,如果i>k,则 在高区寻找第(i-k)个最小元素
29
寻找顺序统计量问题
37
分治法小结
二分搜索 幂乘 合并排序 快速排序 Fibonacci数列 Strassen矩阵乘法 最大元、最小元、寻找顺序统计量问题 最近点对问题 ……
38
算法分析与设计 第五讲
分治法及相关实例分析(续)
1
主要内容
最大元最小元问题 最近点对问题 寻找顺序统计量问题
2
最大元、最小元
给定n个数据元素,找出其中的最大元和 最小元
直接解法:逐个找,用n-1次比较来找出最大元,再 用n-2次比较来找出最小元,比较次数(基本运算) 为2n-3次
3Байду номын сангаас
最大元、最小元
期望线性时间求解方法 伪码
RAND-SELECT(A, p, q, i) ⊳ith smallest of A[p..q] if p= q then return A[p] r←RAND-PARTITION(A, p, q) k←r–p+ 1 ⊳k = rank(A[r]) if i= k then return A[r] if i< k then return RAND-SELECT(A, p, r –1, i) else return RAND-SELECT(A, r + 1, q, i –k)
16
最近点对问题
分析 递归式为
= T (n) 2T (n / 2) + f (n) f ( n) = O ( n) T= '(n) T (n) + O(n lg n)
T (n) = O(n lg n) T '(n) = O(n lg n)
17
寻找顺序统计量问题
求第i小元素问题、选择问题
设集合S中共有n个数据元素,要在S中找出第i小元 素
34
寻找顺序统计量问题
至少有一半组( n/5 /2= n/10组)的 中位数小于或等于x 因此,至少3 n/10个元素≤x
35
寻找顺序统计量问题
至少有一半组( n/5 /2= n/10组)的 中位数小于或等于x 因此,至少3 n/10个元素≤x 至少3 n/10≥x
23
寻找顺序统计量问题
期望线性时间求解方法 示例
24
寻找顺序统计量问题
期望线性时间求解方法 直观分析 一般情况 T (n) = T (9n /10) + Θ(n) = Θ(n) 2 最坏情况 T (n) = T (n − 1) + Θ(n) = Θ(n )
25
寻找顺序统计量问题
期望线性时间求解方法 可以证明,在平均情况下,任何顺序统计 量可以在线性时间内得到
36
寻找顺序统计量问题
分析
1.将输入数组的n个元素分为n/5+1组; 2.寻找这n/5+1组中每一组的中位数; 3.对第二步中找出的n/5+1组中位数,递归调用 SELECT以找到其中位数x; 4.PARTITION,按中位数x对输入数组进行划分,x 为第k小元素; 5.如果i=k,则返回x;否则,如果i<k,则在低区递 归调用SELECT寻找第i小元素;否则,如果i>k,则 在高区寻找第(i-k)个最小元素。
6
一维的最近点对问题
合并
如果最近点对是{p3,q3},即 |p3-q3|<d,则p3和q3 两者与m的距离不超过d,即p3∈(m-d,m], q3∈(m,m+d]
7
最近点对问题
有n个点,输入点集记为P 分解
将P进行分割,分为2部分求最近点对 选择一条垂线L,将P拆分左右两部分为PL和PR
只有两个点
只有三个点
14
最近点对问题
以L为中心线,宽度为2������������的带状区域中的 点,如何筛选,并保证有序(按y坐标升 序排列)
筛选出来之后按照y坐标递增的方式进行排序? 对Y进行预排序,将排好序的Y传入递归主过程
15
最近点对问题
难点
如何在线性时间内获得 YL , YR , X L , X R , Y ′ 若X,Y已按相应坐标排好序
19
寻找顺序统计量问题
求解方法
排序 期望线性时间 最坏情况线性时间
20
寻找顺序统计量问题
排序
合并排序 堆排序
有更好的方法? 分治?
21
寻找顺序统计量问题
期望线性时间求解方法 Θ( n) 分解:用到Random Partition 求解:递归处理 合并
22
寻找顺序统计量问题