算法设计与分析 王红梅 第二版 第4章_分治法

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

2015-5-2
Divide and Conquer Method
2
学习目标
教学重点 教学难点 教学内容 及目标 分治法的设计思想,各种经典问题的分治思想 几何问题的分治算法 知识点 了解 教学要求 理解 掌握 熟练掌 握 √ √ √ √ √
分治法设计思想
归并排序和快速排序 最大子段和问题 棋盘覆盖问题 最近对问题 凸包问题
Divide and Conquer Method
19
4.2.1 归并排序
[想法] 首先将序列划分为两个子序列,如子序列长度为 1, 则划分结束,否则继续执行划分,结果将具有 n个待排序的 记录序列划分为n个长度为1的有序子序列;然后两两合并, 得到n/2个长度为2的有序子序列,再进行两两合并…直到得 到一个长度为n的有序序列。
2015-5-2
Divide and Conquer Method
20
4.2.1 归并排序
算法4.3——归并排序 void MergeSort(int r[ ], int r1[ ], int s, int t) //r[ ]—原序列数组,r1[ ]—归并后序列数组 { if (s= =t) r1[s]=r[s]; r[s],…,r[m] r[m+1],…,r[t] else { m=(s+t)/2; Mergesort(r, r1, s, m); //归并排序前半个子序列 Mergesort(r, r1, m+1, t); //归并排序后半个子序列 Merge(r1, r, s, m, t); //合并两个已排序的子序列 } }
2015-5-2 Divide and Conquer Method 22
4.2.1 归并排序
二路归并排序的合并步骤的时间复杂性为 O(n) , 所以,二路归并排序算法存在如下递推式:
1 T (n) = 2T ( n 2 ) + n
n =2 n >2
根据2.1.5节的通用分治递推定理,二路归并排序的 时间代价是O(nlog2n)。
2015-5-2 Divide and Conquer Method 25
17
4.2.1 归并排序
归并排序
二路归并排序的分治策略是: (1)划分:将待排序序列r1, r2, …, rn划分为两个长 度相等的子序列r1, …, rn/2和rn/2+1, …, rn; ( 2 )求解子问题:分别对这两个子序列进行排序, 得到两个有序子序列;
( 3 )合并:将这两个有序子序列合并成一个有序 序列。
算法设计与分析—本科生课程
Design and Analysis of Algorithm
第4章 分治法
海南大学信息科学技术学院 College of Information Science and Technology, Hainan University
本章要点
4.1 概 述 4.2 排序问题中的分治法 4.3 组合问题中的分治法 4.4 几何问题中的分治法 阅读材料 递归函数的执行过程
原问题划分成k个较小规模的子问题,对这k个子问题分别求 解。如果子问题的规模仍然不够小,则再将每个子问题划分
为k个规模更小的子问题,如此分解下去,直到问题规模足够
小,很容易求出其解为止,再将子问题的解合并为一个更大 规模的问题的解,自底向上逐步求出原问题的解。
2015-5-2
Divide and Conquer Method
32 31
分解问题
求解每个子问题
3
3 9 合并子问题的解
不是所有的分治法都比简单的蛮力法更有效。
概 述
4.1.1 分治法的设计思想 4.1.2 一个简单的例子——数字旋转方阵
2015-5-2
Divide and Conquer Method
11
数字旋转方阵
[问题] 输出如图4.3(a)所示N*N(1≤N≤10)的数字旋转方阵 [思路]用二维数组表示方阵,从外层向里层填数,如图(b)所示, 将每一层的填数过程分为ABCD四个区域。每填一层size减2, 终止条件是size≤1。
当n=0时 0 当n=1时 T(n) = 1 T(n-2)+4(n-1) 当n>1时
设n为偶数,用扩展递归技术解此递推式,得 T(n)=T(n-2)+4(n-1)=T(n-4)+4(n-3)+4(n-1)
=T(0)+…+4(n-5)+4(n-3)+4(n-1)=O(n2)
2015-5-2 Divide and Conquer Method 15
i=s; j=m+1; k=s; i j while (i<=m && j<=t) r[s],…,r[m] r[m+1],…,r[t] { if (r[i]<=r[j]) r1[k++]=r[i++]; //取r[i]和r[j]中较小者放入r1[k] else r1[k++]=r[j++]; } k r1[s],…,r1[m],r1[m+1],…,r1[t] if (i<=m) while (i<=m) //若第一个子序列没处理完,则进行收尾处理 r1[k++]=r[i++]; else while (j<=t) //若第二个子序列没处理完,则进行收尾处理 r1[k++]=r[j++]; }

2015-5-2
Divide and Conquer Method
3
概 述
4.1.1 分治法的设计思想 4.1.2 分治法的求解过程
2015-5-2
Divide and Conquer Method
4
概述-分治法思想
分治法的设计思想:
将一个难以直接解决的大问题,划分成一些规模较小的
子问题,以各个击破,分而治之。更一般地说,将要求解的
5
概述-分治法思想
启发式规则:
1. 平衡子问题:最好使子问题的规模大致相同。也就是将一 个问题划分成大小相等的k个子问题(通常k=2、4,…),这 种使子问题规模大致相等的做法是出自一种平衡(Balancing) 子问题的思想,它几乎总是比子问题规模不等的做法要好。 2. 独立子问题:各子问题之间相互独立,这涉及到分治法的 效率,如果各子问题不是独立的,则分治法需要重复地解公 共的子问题。
本章要点
4.1 概 述 4.2 排序问题中的分治法 4.3 组合问题中的分治法 4.4 几何问题中的分治法 阅读材料 递归函数的执行过程
2015-5-2
Divide and Conquer Method
16
排序问题中的分治法
4.2.1 4.2.2
归并排序 快速排序
2015-5-2
Divide and Conquer Method
2015-5-2 Divide and Conquer Method 21
4.2.1 归并排序
算法4.4——合并有序子序列 void Merge(int r[ ], int r1[ ], int s, int m, int t)
{ // i,j分别指向两个待合并的有序子序列,k指向最终有序序列的当前记录
2015-5-2
Divide and Conquer Method
23
4.2.2 快速排序
快速排序的分治策略
( 1 )划分:选定一个记录作为轴值,以轴值为基准将整个序 列划分为两个子序列r1 … ri-1和ri+1 … rn,前一个子序列中记录 的值均小于或等于轴值,后一个子序列中记录的值均大于或等 于轴值; [ r1 … … ri-1 ] ri [ ri+1 … … rn ] (2)求解子问题:分别对 划分后的每பைடு நூலகம்个子序列递归 处理; 均 ≤ri 轴值 均 ≥ri (3)合并:由于对子序列 位于最终位置 r1 … ri-1和ri+1 … rn的排序是 就地进行的,所以合并不需 要执行任何操作。
2015-5-2 Divide and Conquer Method 24
4.2.2 快速排序
以第一个记录为轴值(可随机),对待排序序列进行划分的过程: ( 1 )初始化:取第一个记录作为基准,设置两个参数 i , j 分别 用来指示将要与基准记录进行比较的左侧记录位置和右侧记录位 置,也就是本次划分的区间; (2)右侧扫描过程:将基准记录与j指向的记录进行比较,如果 j指向记录的关键码大,则j--,即前移一个记录位置。重复右侧扫 描过程,直到右侧的记录小(即反序),若i<j,则将基准记录 与j指向的记录进行交换; (3)左侧扫描过程:将基准记录与i指向的记录进行比较,如果i 指向记录的关键码小,则 i++,即后移一个记录位置。重复左侧 扫描过程,直到左侧的记录大(即反序),若i<j,则将基准记 录与i指向的记录交换;
2015-5-2
Divide and Conquer Method
6
概述-分治法思想
分治法的典型情况
原问题 的规模是n
子问题1 的规模是n/2
子问题2 的规模是n/2
子问题1的解
子问题2的解
原问题的解
2015-5-2 Divide and Conquer Method 7
概述-分治法的求解过程
一般来说,分治法的求解过程由以下三个阶段组成: (1)划分:既然是分治,当然要把规模为n 的原问题划 分为 k 个规模较小的子问题,并尽量使这 k 个子问题的规 模大致相同。 (2)求解子问题:各子问题的解法与原问题的解法通常 是相同的,可以用递归的方法求解各个子问题,有时递归 处理也可以用循环来实现。 (3)合并:把各个子问题的解合并起来,合并的代价因 情况不同有很大差异,分治算法的有效性很大程度上依赖 于合并的实现。
2015-5-2
Divide and Conquer Method
12
数字旋转方阵
算法4.1:数字旋转方阵Full 输入:当前层左上角要填的数字number,左上角的坐标begin, 方阵的阶数size
输出:数字旋转方阵
1. 如果size=0,则算法结束; 2. 如果size=1,则data[begin][begin]=number,算法结束; 3. 初始化行、列下标i=begin,j=begin; 4. 重复下述操作size-1次,填写区域A 1. Data[i][j]=number; number++; i++;
2015-5-2 Divide and Conquer Method 13
数字旋转方阵
5. 重复下述操作size-1次,填写区域B 1. Data[i][j]=number; number++; j++; 6. 重复下述操作size-1次,填写区域C 1. Data[i][j]=number; number++; i--; 7. 重复下述操作size-1次,填写区域D
2015-5-2
Divide and Conquer Method
9
例:计算an,应用分治技术得到如下计算方法:
a
时间性能 O(nlog2n) 而蛮力法的 时间性能为 O(n)
n
= n a
a n 2 * a
34
2
如果 n = 1 如果 n > 1
32 31 31 3 9 81 31 3
2015-5-2
Divide and Conquer Method
8
概述-分治法的求解过程
分治法的一般过程
1 DivideConquer(P) //求解规模为n的问题P 2 { 3 if (P的规模足够小) 直接求解P; 分解为k个子问题P1, P2, …, Pk; 4 for (i=1;i<=k;i++) 5 yi=DivideConquer(P); //解各子问题,通常采用递归 6 return Merge (y1, y2, …, yk ); //将各子问题的解合并为原问题的解 7 }
1. Data[i][j]=number; number++; j--;
8. 递归调用函数Full在size-2阶方阵中左上角begin+1处从数字 number开始填数
2015-5-2
Divide and Conquer Method
14
数字旋转方阵
[算法分析]填写n阶方阵,四个区域由4个循环实现,每个循环 均执行n-1,然后执行递归调用,填写n-2阶方阵。递推式:
2015-5-2 Divide and Conquer Method 18
4.2.1 归并排序
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
递归处理
合并解
2015-5-2
相关文档
最新文档