算法-分治法演示课件
合集下载
分治算法详解ppt课件
精选ppt课件
12
合并排序
&最坏时间复杂度:O(nlogn) &平均时间复杂度:O(nlogn) &辅助空间:O(n)
精选ppt课件
13
棋盘覆盖
在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格 不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋 盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的 特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不 得重叠覆盖。
chessBoard(tr, tc+s, tr+s-1, tc+s, s);} // 覆盖左下角子棋盘
// 覆盖左上角子棋盘
if (dr >= tr + s && dc < tc + s)
iefl/cs(/deh特re{<s/殊/st此rB方+o棋复格as盘r在&杂d中&(此tr度d无,棋ctc特分盘<, d殊t中cT r析,方+d(ck 格s,))s) ; 4T(ke O l/cbs1 /(eho特1 )ae{) r/s殊d/s[用O tB方r o+(格t1 a号s)r在]d[Lt(此c型tk kr++棋骨s s,盘牌t-0 0 c中覆1, ]d盖=r, t右d;c上, s角);
算法总体思想
n 将求出的小规模的问题的解合并为一个更大规模的问 题的解,自底向上逐步求出原来问题的解。
分分治割T法成(n的一) 设些计规模思较想是小=,的相将同一n问个题难,以以直便接各解个决击的破大,问题,
分而治之。
n/2
n/2
n/2
n/2
T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4精)T选(np/4p)t课T件(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/54)T(n/4
五大常用算法ppt课件
桥了。
A B→ 2 A←1
AC → 5 A←1
AD → 8
一共就是2+1+5+1+8=17分钟。
Your company slogan
贪心算法
但其实有更快的办法: AB→2 A←1 CD→8 B←2 AB→2
一共是2+1+8+2+2=15分钟。这个办法的聪明之处在于让两个走得最慢的人同时过桥, 这样花去的时间只是走得最慢的那个人花的时间,而走得次慢的那位就不用另花时间过 桥了。可以把所有可能的方案都列举一遍,就会发现这是最快的方案了。
Your company slogan
贪心算法
2015年周得水等人提出一种基于Dijkstra的贪心算法来实现模糊连接度的快速计算。 基于模糊连接度的图像分割过程如下: (1)由用户在图像中选取种子点; (2)计算图像中各点相对于种子点的模糊连接度,同时得到各点到种子点的最优路径; (3)对得到的最优路径进行各点相对于种子点的属性相似度计算,同时得到图像中各点新 的隶属度; (4)用户通过选取阈值来分割图像。
1. if |P|≤n0
2. then return(ADHOC(P)) 3. 将P分解为较小的子问题 P1 ,P2 ,...,Pk
4. for i←1 to k 5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi 6. T ← MERGE(y1,y2,...,yk) △ 合并子问题
后将各子问题的解合并得到原问题的解。(分治与递归)
适用情况: 1) 该问题的规模缩小到一定的程度就可以容易地解决; 2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质; 3) 利用该问题分解出的子问题的解可以合并为该问题的解; 4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
《算法分治法》课件
分治算法的原理还体现在将一个复杂的问题分解为若干个相 互关联、相互依赖的小问题,这些小问题之间存在着一定的 规律和联系,通过解决这些小问题,可以找出原问题的解决 方案。
分治算法的步骤
分治算法的步骤还包括对问题进行归纳和分类,确定 问题的规模和复杂度,选择合适的分治策略和算法实 现方式等。
单击此处添加正文,文字是您思想的提一一二三四五 六七八九一二三四五六七八九一二三四五六七八九文 ,单击此处添加正文,文字是您思想的提炼,为了最 终呈现发布的良好效果单击此4*25}
分治算法的核心思想是将一个复杂的问题分解为若干个规模较小、相互独立、与 原问题形式相同的子问题,递归地解这些子问题,然后再将子问题的解合并,以 求得原问题的解。
分治算法的原理
分治算法的原理是利用问题的相似性,将大问题分解为小问 题,将复杂问题转化为简单问题,从而降低问题的难度,提 高解决问题的效率。
探索分治算法与其他算法(如贪心算法、动态规划等)的结合
,实现更高效的算法设计。
分治算法的理论基础研究
02
深入探讨分治算法的理论基础,为算法设计和优化提供理论支
持。
分治算法在实际问题中的应用研究
03
针对实际问题,研究分治算法的应用场景和解决方案,推动算
法的实际应用。
THANKS
感谢观看
对于可以并行处理的子问题,可以使 用多线程或分布式计算等技术进行并 行处理,进一步提高算法效率。
动态规划
动态规划是一种常用的优化技术,通 过将子问题存储在表格中并逐步更新 ,可以避免重复计算,提高算法效率 。
分治算法在实际项目中的应用案例
归并排序
归并排序是一种典型的分治算法,通过递归地将数组分解为若干个子数组,然后合并子数 组得到有序数组。在实际应用中,归并排序广泛应用于各种排序场景。
分治算法的步骤
分治算法的步骤还包括对问题进行归纳和分类,确定 问题的规模和复杂度,选择合适的分治策略和算法实 现方式等。
单击此处添加正文,文字是您思想的提一一二三四五 六七八九一二三四五六七八九一二三四五六七八九文 ,单击此处添加正文,文字是您思想的提炼,为了最 终呈现发布的良好效果单击此4*25}
分治算法的核心思想是将一个复杂的问题分解为若干个规模较小、相互独立、与 原问题形式相同的子问题,递归地解这些子问题,然后再将子问题的解合并,以 求得原问题的解。
分治算法的原理
分治算法的原理是利用问题的相似性,将大问题分解为小问 题,将复杂问题转化为简单问题,从而降低问题的难度,提 高解决问题的效率。
探索分治算法与其他算法(如贪心算法、动态规划等)的结合
,实现更高效的算法设计。
分治算法的理论基础研究
02
深入探讨分治算法的理论基础,为算法设计和优化提供理论支
持。
分治算法在实际问题中的应用研究
03
针对实际问题,研究分治算法的应用场景和解决方案,推动算
法的实际应用。
THANKS
感谢观看
对于可以并行处理的子问题,可以使 用多线程或分布式计算等技术进行并 行处理,进一步提高算法效率。
动态规划
动态规划是一种常用的优化技术,通 过将子问题存储在表格中并逐步更新 ,可以避免重复计算,提高算法效率 。
分治算法在实际项目中的应用案例
归并排序
归并排序是一种典型的分治算法,通过递归地将数组分解为若干个子数组,然后合并子数 组得到有序数组。在实际应用中,归并排序广泛应用于各种排序场景。
算法-第4章-分治法
折半查找举例:
位置:0 1 2 3 4 5 6 7 8 9 10 11 12 值: 3,14,27,31,39,42,55,70,74,81,85,93,98 K=70 ↑ ↑ ↑ 迭代1 l=0 m=6 r=12 迭代2 l m=9 r 迭代3 l r 结果 m= (7+8)/2=7
树-"a" 树-"+" 输出 -"+" 遍历 L-"a" 遍历 R-"*" 输出 -"a" 遍历 L-"^" 遍历 R-"^" 树-"*" 输出 -"*" 遍历 L-"b" 遍历 R-"-" 树-"e" 输出 -"e" 遍历 L-"^" 遍历 R-"^" 树-"f" 输出 -"f" 遍历 L-"^" 遍历 R-"^" 树-"b" 输出 -"b" 遍历 L-"^" 遍历 R-"^" 树-"-" 输出 -" -" 遍历 L-"c" 遍历 R-"d" 树-"c" 输出 -"c" 遍历 L-"^" 遍历 R-"^" 树-"d" 输出 -"d" 遍历 L-"^" 遍历 R-"^"
二路归并
注:归并 [2,3,8,9] 与[1,4,5,7] 的过程: 从两个序列的头部开始归并:2与1比较,1被移到结果序列;4 与2比较,2被移入结果序列;4与3比较,3被放入结果序列;4和8 比较,4被放入结果序列, 8和7比较...,
人工智能算法Python语言版PPT第2章分治法
(3) 将结果从C中填回原列表
indexC←1 for i←finalStart to finalEnd do list[i]←result[indexC] indexC←indexC+1 end for
无需比较操作!
合并排序 (8)
MergeLists的最优情况
MergeSort算法的执行时间
- 列表A中所有元素都不大于B中最小 - nA 次比较 (n/2) - 例如:A={1, 2, 3}, B={4, 5 ,6}
T
(n)
O(1) 2T (n
/
2)
O(n)
n 1 n 1
O(n log n)
MergeLists的最坏情况
- 列表A列表 B中元素交叉排列时
- 每执行一次比较操作,将A或B中的 一个元素移到列表C中
应用背景和动机 (1)
对将这k要个求子解问的题较分别大求规解模的问题分割成k个更小规模的子问题。
- 如果子问题的规模仍然不够小,再划分为k个子问题
- 如此递归地进行下去,直到问题规模足够小,很容易求出其解为止
=
n
T(n)
T(n/2)
T(n/2)
T(n/2)
T(n/2)
应用背景和动机 (2)
对这k个子问题分别求解,其中分解直到问题规模足够小,很容易求 出其解为止
提纲
应用背景和动机 分治法的基本思想和一般步骤 分治法的适用条件 分治法的复杂度分析方法 合并排序 总结
合并排序 (1)
引例:合并两个有序子列表
{179, 285, 351}, {310, 312, 652, 800}
(1) 179<310: {179} (2) 285<310: {179, 285} (3) 351>310: {179, 285, 310} {179, 285, 351}, {310, 312, 652, 800}
算法-分治法演示课件
//对应情况①,递归求解 rightsum=MaxSum(a, center+1, right);
//对应情况②,递归求解
2020/6/28
30
s1=0; lefts=0;
//以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
s2=0; rights=0;
//再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
//计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
2020/6/28
15
[ r1 … … ri-1 ] ri [ ri+1 … … rn ] 均≤ri 轴值 均≥ri 位于最终位置
❖归并排序按照记录在序列中的位置对序列进行划分, ❖快速排序按照记录的值对序列进行划分。
2020/6/28
16
以第一个记录作为轴值,对待排序序列进行划分的过程为: (1)初始化:取第一个记录作为基准,设置两个参数i,j;
2020/6/28
13
算法4.4——合并有序子序列
void Merge(int r[ ], int r1[ ], int s, int m, int t) {
i=s; j=m+1; k=s; while (i<=m && j<=t) {
//对应情况②,递归求解
2020/6/28
30
s1=0; lefts=0;
//以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
s2=0; rights=0;
//再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
//计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
2020/6/28
15
[ r1 … … ri-1 ] ri [ ri+1 … … rn ] 均≤ri 轴值 均≥ri 位于最终位置
❖归并排序按照记录在序列中的位置对序列进行划分, ❖快速排序按照记录的值对序列进行划分。
2020/6/28
16
以第一个记录作为轴值,对待排序序列进行划分的过程为: (1)初始化:取第一个记录作为基准,设置两个参数i,j;
2020/6/28
13
算法4.4——合并有序子序列
void Merge(int r[ ], int r1[ ], int s, int m, int t) {
i=s; j=m+1; k=s; while (i<=m && j<=t) {
算法分析与设计PPT教学课件 Algorithms Chapter 4 分治法
n>1
Memory 冒泡 合并 Time
15
Example of merge sort
Example of merge sort sorting a list of random numbers
16
练习 p98-11 Tromino谜题
如何将右图中L型瓦片覆盖到一个缺了一 个方块的2n × 2n的棋盘?
//输入:两个有序数组B[0..p-1]和C[0..q-1]
//输出:非降序列数组A-0..p+q-1] i0; j0; k0; while (i<p and j<q do){
if (n>1){
copy A[0.. [n/2]-1] to B[0..[n/2]-1] ; copy A[[n/2]..n-1] to C[0..[n/2]-1]; Mergesort(B[0..[n/2]-1]);
5
分治法的抽象化控制
1. 2. 3. 4. 5. 6. 7. Divide-and-Conquer(P) if |P|≤n0 判断输入规模是否足够的小 then return(ADHOC(P))//直接解小规模的问题P 将P分解为较小的子问题 P1 ,P2 ,...,Pk for i←1 to k do yi ← Divide-and-Conquer(Pi)//递归解决Pi T ← MERGE(y1,y2,...,yk) // 合并子问题 return(T)
...... ......
I2=(n-[n/2], A[[n/2]-1…n-1])
...... ......
Ih=(1,A[0])
Ii=(1,A[1])
Ij=(1,A[m])
Ik=(1,A[n])
2009-2010-2《算法分析》ppt-3分治法
合并排序
复杂度分析 O(1) n 1 T (n) 2T (n / 2) O(n) n 1 T(n)=O(nlogn) 渐进意义下的最优算法
合并排序(P97)
初始序列
[49] [38] [65] [97] [76] [13] [27]
第一步
[38 49]
[65 97]
[13 76]
例如正整数6有如下11种不同的划分: 6; 5+1; 4+2,4+1+1; 3+3,3+2+1,3+1+1+1; 2+2+2,2+2+1+1,2+1+1+1+1; 1+1+1+1+1+1。
整数划分问题
前面的几个例子中,问题本身都具有比较明显的 递归关系,因而容易用递归函数直接求解。 在本例中,如果设p(n)为正整数n的划分数,则难 以找到递归关系,因此考虑增加一个自变量:将 最大加数n1不大于m的划分个数记作q(n,m)。可以 建立q(n,m)的如下递归关系。
大整数乘法
例 A=2348,B=3825 a1=23,a2=48,b1=38,b2=25 p=(a1+a2)(b1+b2)=71 *63=4473 q=a1b1=874, r=a2b2=1200 AB=8740000+(4473-874-1200)*100+1200 =8740000+239900+1200 =8981100
分治法的复杂性分析
O(1) n 1 T (n) kT (n / m) f (n) n 1
算法分析与设计分治法ppt课件
定理2.3 :设A(1:n)含有n(n≥1)个不同的元素,排序为 A(1)<A(2)<…<A(n)。又设以比较为基础去判断是否x∈A(1:n) 的任何算法在最坏情况下所需的最小比较次数是FIND(n),那么 FIND(n)≥[log(n+1)]
证明 若一棵二元树的所有内部结点所在的级数小于或等于级数k,
195 142 111 2 1 NO
X=82 Low high mid
195 697
898 OK
二分检索算法正确性的证明
用五个特性判断是否是一个算法
根据算法的描述,满足五个特性的才是算法
证明算法是否正确
如果n=0,则不进入循环,j=0,算法终止 否则就会进入循环与数组A中的元素进行比较 如果x=A[mid],则j=mid,检索成功,算法终止 否则,若x<A(mid),则缩小到A(low)和A(mid-1)之间
I=(n,A(1),…,A(n))
I1=([n/2],A(1),…,A([n/2])) I2=(n-[n/2],A([n/2]+1),…,A(n))
… …
递归求取最大和最小元素
Procedure MAXMIN(i,j,fmax,fmin) integer i,j;global n,A(1:n) case
=2k+3*2k-1-3
=5n/2-3 当n较大时,比较次数会远远大于直接比较算法
2.4 归并分类(排序)
问题描述 给定一个含有n个元素(或叫关键字)的集合,把它们按一 定的次序分类(如非降次序排序)
一般方法(插入法) For j2 to n do
将A(j)放到已分类集合A(1:j-1)的正确位置上 Repeat
二分检索的时间复杂度
证明 若一棵二元树的所有内部结点所在的级数小于或等于级数k,
195 142 111 2 1 NO
X=82 Low high mid
195 697
898 OK
二分检索算法正确性的证明
用五个特性判断是否是一个算法
根据算法的描述,满足五个特性的才是算法
证明算法是否正确
如果n=0,则不进入循环,j=0,算法终止 否则就会进入循环与数组A中的元素进行比较 如果x=A[mid],则j=mid,检索成功,算法终止 否则,若x<A(mid),则缩小到A(low)和A(mid-1)之间
I=(n,A(1),…,A(n))
I1=([n/2],A(1),…,A([n/2])) I2=(n-[n/2],A([n/2]+1),…,A(n))
… …
递归求取最大和最小元素
Procedure MAXMIN(i,j,fmax,fmin) integer i,j;global n,A(1:n) case
=2k+3*2k-1-3
=5n/2-3 当n较大时,比较次数会远远大于直接比较算法
2.4 归并分类(排序)
问题描述 给定一个含有n个元素(或叫关键字)的集合,把它们按一 定的次序分类(如非降次序排序)
一般方法(插入法) For j2 to n do
将A(j)放到已分类集合A(1:j-1)的正确位置上 Repeat
二分检索的时间复杂度
算法分析与设计第四章2分治法归并分类PPT课件
{
item=a[j];i=j-1;
while(i>=1&&item<a[i])
{
a[i+1]=a[i];i=i-1;
}
a[i+1]=item;
}
}
2008-09-01
i指示的是j之前的一位, 即当前已排序子表的 最末一个元素的下标
4
性能分析
输入数据按非增次序排列,每次内层while循 环执行j次(j=1,2,…, n-1)。
i 1 2 3 4 5 6 7 8 9 10 a[i] 6 7 8 9 2 3 4 5 0 1
i 1 2 3 4 5 6 7 8 9 10 a[i] 2 3 4 5 6 7 8 9 0 1
步骤4:length=8
i 1 2 3 4 5 6 7 8 9 10 a[i] 0 1 2 3 4 5 6 7 8 9
16
public static void MergeSort(int n,int DataLength) { //n为待合并数据个数
int i,t; //循环计数变量 i=1; //还有两段长度为DataLength的list可合并 while(i<=(n-2*DataLength+1)) {
Merge(i, i+DataLength-1, i+2*DataLength-1); i=i+2*DataLength; } if(i+DataLength<n) {//合并两段list,一段长度为DataLength,另一段长度不足DataLength Merge(i, i+DataLength-1, n); } else {//将剩下一段长度不足DataLength的list中的值不变 } }
分治算法PPT
第一步
[38 49] [65 97] [13 76] [27]
第二步 第三步
[38 49 65 97]
[13 27 76]
18
[13 27 38 49 65 76 97]
归并排序主函数
void mergesort(int A[], int l, int r, int T[]) {
if(l < r) { int mid = (l + r) / 2; //二分 mergesort(A, l, mid, T);//继续对左子序列递归排序 mergesort(A, mid+1, r, T);//继续对右子序列递归排序 merge(A, l, mid, r, T); //合并
8
方法1
假设袋中有n个金块。可以通过n-1次比较找到最重 的金块。然后可以从余下的n-1个金块中用类似的方 法通过n-2次比较找出最轻的金块。这样,比较的总 次数为2n-3。具体的实现方法如下:
max = a[1]; min = a[1]; for(i=2; i<=n; i++) //2n-2次比较 {
问题,最后合并其结果就得到原问题的解。当分解(Divide):将原问题分成一系列子问题。 解决(Conquer):递归地解各子问题。若子问题
足够小,则可直接求解。 合并(combine);将子问题的结果合并成原问题
的解。
14
分治思想
问题的分解
方法1:每枚硬币都至少进行了一次比较,而有一枚硬 币进行了15次比较
方法2:每一枚硬币只进行了一次比较 方法3:将硬币分为两组后一次比较可以将硬币的范
围缩小到了原来的一半,这样充分地利用了只有1枚 伪币的基本性质。
第二讲-分治专题讲座
P
pn22
s1
S
n
pnkk
sk
精品课件
三、分治法的抽象控制策略
设: 原问题输入为a[n],简记为(1,n); 子问题输入为a[p]~a[q],1≤p≤q≤n,简记为(p,q)。
已知: SOLUTION; int divide (int, int); int small (int, int); SOLUTION conquer (int, int); SOLUTION combine (SOLUTION, SOLUTION);
精品课件
• 平均情况分
5
析
内部路径长度之
2
7
和:I
1
3
外部路径长度之
6
8
和:E, E=I+2n。
4
9
成功检索的平
均比较次数:
S(n)=(I/n)+1
不成功检索的平均比较次数: U(n)=E/(n+1) 由此可得:S(n)=(1+1/n)U(n)-1
因为:U(n)=O(log n),所以: S(n)=O(log n)
(k-1, a[0],…,a[k-2], x) a[k],…,a[n-1], x)
(1, a[k-1], x)
(n-k,
精品课件
三、递归算法
int BinSearch1(p, q, x) { int k=(p+q)/2;
if(q<p) return –1; /* 参数错误 */ if(x==a[k]) return k; if(x<a[k]) return BinSearch1(p, k-1, x); if(x>a[k]) return BinSearch1(k+1, q, x); }
算法5_分治法
T(n)
=
n
T(n/2)
T(n/2)
T(n/2)
T(n/2)
ch5.5
对这k个子问题分别求解。如果子问题的规模仍然不够 小,则再划分为k个子问题,如此递归的进行下去,直 到问题规模足够小,很容易求出其解为止。
T(n)
n/2
=
n/2
n
n/2 n/2
T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4)
ch5.24
分治法的复杂性分析
一个分治法将规模为n的问题分成a个规模为n/b的子问题去解。 设:S求解规模为1的问题,需要耗费常数单位时间c。 再设:进行问题分解及将a个子问题的解合并得到原始问题的解 需用f(n)个单位时间的工作量。 则当f(n)=cnk时,用T(n)表示该分治法解规模为|P|=n的问 题所需的计算时间有: c n 1 T (n) (5-1) k n 1 a T ( n / b ) cn 令n=bm (即m=logbn),通过迭代法可求得方程的解:
这条特征是应用分治法的前提,它也是大多数问题可以满 足的,此特征反映了递归思想的应用。
ch5.10
分治法的适用条件
分治法所能解决的问题一般具有以下几个特征: 该问题的规模缩小到一定的程度就可以容易地解 决; 该问题可以分解为若干个规模较小的相同问题; 利用该问题分解出的子问题的解可以合并为该问 题的解;
ch5.6
将求出的小规模的问题的解合并为一个更大规模的问 题的解,自底向上逐步求出原来问题的解。
T(n)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
i=1
2
因此,时间复杂度为O(n2)。
2020/6/28
23
平均情况:设基准记录的关键码第k小(1≤k≤n),则有:
T (n )=1 n(T (n k)+ T (k 1 )+ )n=2 nT (k)+ n
nk= 1
nk= 1
这是快速排序的平均时间性能,可以用归纳 法证明,其数量级也为O(nlog2n)。
当序列中所有整数均为负整数时,其最大子段和为0。 如,序列(-20, 11, -4, 13, -5, -2)的最大子段和为:4 ak = 20
k=2
2020/6/28
26
先考虑最大子段和问题的简单算法
最大子段和问题的分治策略是: (1)划分:按照平衡子问题的原则,将序列(a1, a2, …, an)划分成长度相同的两个子序列(a1, …, a n 2 )和(a n 2 +1, …, an),则:
//对应情况①,递归求解 rightsum=MaxSum(a, center+1, right);
//对应情况②,递归求解
2020/6/28
30
s1=0; lefts=0;
//以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
13
27
38 50
55
65 49
i
j
i
j
13 27 38 49 50 55 65
2020/6/28
20
算法4.6——快速排序
void QuickSort(int r[ ], int first, int end)
{ if (first<end) { pivot=Partition(r, first, end); //问题分解,pivot是轴值在序列中的位置 QuickSort(r, first, pivot-1); //递归地对左侧子序列进行快速排序 QuickSort(r, pivot+1, end); //递归地对右侧子序列进行快速排序
2020/6/28
15
[ r1 … … ri-1 ] ri [ ri+1 … … rn ] 均≤ri 轴值 均≥ri 位于最终位置
❖归并排序按照记录在序列中的位置对序列进行划分, ❖快速排序按照记录的值对序列进行划分。
2020/6/28
16
以第一个记录作为轴值,对待排序序列进行划分的过程为: (1)初始化:取第一个记录作为基准,设置两个参数i,j;
}
s2=0; rights=0;
//再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
//计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
快速排序的空间复杂性如何?
2020/6/28
24
4.3 组合问题中的分治法
4.3.1 最大子段和问题 4.3.2 棋盘覆盖问题 补充: 循环赛日程安排问题
2020/6/28
25
ቤተ መጻሕፍቲ ባይዱ 4.3.1 最大子段和问题
子段和给问定题由要n个求整该数序组列成形的如序j列a k 的(a1最, a大2,值…(,1≤ani)≤,j最≤大n)。 k =i
18
算法4.5——一次划分
int Partition(int r[ ], int first, int end)
{ i=first; j=end; //初始化 while (i<j)
{
while (i<j && r[i]<= r[j]) j--; //右侧扫描
if (i<j) {
r[i]←→r[j];
分析时 间性能
an
a
=
a
n
2
´ a n 2
34
如果 n = 1 如果 n > 1
32
32
分解问题
31
31
31
31
求解每个子问题
3
3
3
3
9
9
合并子问题的解
81
❖ 不是所有的分治法都比简单的蛮力法更有效。
2020/6/28
7
4.1.2 数字旋转方阵
问题:输出NN(1N10)数字旋转方阵。
1 20 19 18 17 16 2 21 32 31 30 15 3 22 33 36 29 14 4 23 34 35 28 13 5 24 25 26 27 12 6 7 8 9 10 11
(2)右侧扫描过程:
(3)左侧扫描过程:
(4)重复(2)(3)步,直到i与j指向同一位置,即基准记 录最终的位置。
2020/6/28
17
一次划分示例
38
55 27
50 13 49
65
i
jj
j
13 27 55 50 38 49 65
i
ii
j
13 27 38 50 55 49 65
ij j j
2020/6/28
2020/6/28
10
r1 … … rn/2 rn/2+1 … … rn r‘1<… …<r’n/2 r’n/2+1<… …<r’n
划分 递归处理
r''1<……<r''n/2<r''n/2+1 <……<r ''n
合并解
举例:8 3 2 6 7 1 5 4
2020/6/28
11
算法4.3——归并排序
//将较小记录交换到前面
i++;
}
while (i<j && r[i]<= r[j]) i++; //左侧扫描
if (i<j) {
r[j]←→r[i];
//将较大记录交换到后面
j--;
}
} retutn i; // i为轴值记录的最终位置
}
2020/6/28
19
以轴值为基准将待排序序列划分为两个子序 列后,对每一个子序列分别递归进行排序。
如果子问题的规模仍然不够小,可继续分解下去。
2020/6/28
3
分治法的求解过程:分-治-合
(1)划分:把规模为n的原问题划分为k个规模较 小的子问题,并尽量使这k个子问题的规模大致相同。
(2)求解子问题:各子问题的解法与原问题的解 法通常是相同的,可以用递归的方法求解各个子问题。
(3)合并:把各个子问题的解合并起来,分治算 法的有效性很大程度上依赖于合并的实现。
2020/6/28
4
启发式规则:
1. 平衡子问题:最好使子问题的规模大 致相同。 2. 独立子问题:各子问题之间相互独立。
2020/6/28
5
分治法的典型情况
原问题 的规模是n
子问题1 的规模是n/2
子问题1的解
子问题2 的规模是n/2
子问题2的解
原问题的解
2020/6/28
6
例:计算an,应用分治技术得到如下计算方法:
r1[k++]=r[j++]; }
2020/6/28
14
4.3.2 快速排序
快速排序的分治策略是: (1)划分:选定一个记录作为轴值,以轴值为基准 将整个序列划分为两个子序列;
(2)求解子问题:分别对划分后的每一个子序列 递归处理; (3)合并:由于对子序列r1 … ri-1和ri+1 … rn的排序 是就地进行的,所以合并不需要执行任何操作。
}
}
2020/6/28
21
最好情况:每次划分后把待划分区间划分为长度相等的两个 子序列。 在具有n个记录的序列中,一次划分需要对整个待划分序列 扫描一遍,则所需时间为O(n)。 设T(n)是对n个记录的序列进行排序的时间,则有: T(n)=2 T(n/2)+n
=2(2T(n/4)+n/2)+n=4T(n/4)+2n =4(2T(n/8)+n/4)+2n=8T(n/8)+3n
if (sum<rightsum) sum=rightsum;
}
return sum;
}
2020/6/28
31
算法的时间性能:对应划分得到的情况①和
②,需要分别递归求解,对应情况③,两个并列 for循环的时间复杂性是O(n),所以,存在如下递 推式:
T(n)= 2T(n2)1+n
n=1 n>1
从而可得算法4.7的时间复杂性为 O(nlog2n)。
2020/6/28
27
① a1, …, an的最大子段和=a1, …,an 2的最大子段和; ② a1, …, an的最大子段和=an 2+1, …, an的最大子段和;
j
③ a1, …, an的最大子段和= a k ,且 k =i
1 i n 2 ,n 2 + 1 j n
(2)求解子问题:对于划分阶段的情况①和②可递归求解,
sum=0; if (left= =right) { //如果序列长度为1,直接求解
if (a[left]>0) sum=a[left]; else sum=0; } else { center=(left+right)/2; //划分 leftsum=MaxSum(a, left, center);