计算机算法设计与分析基础(第五章减治法)

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



在排列的每一分量上画一个箭头。 求最大的移动整数k,不断移动元素,直到没有元素 可移动为止,掉转所有大于k 的整数方向。 移动元素:如果分量k 的箭头指向一个相邻的较小 元素,则该分量在排列中是移动的。 例n=3,从123开始:
1 23 1 32 3 1 2 32 1 23 1 2 1 3
算法分析与设计
Analysis and Design of Computer Algorithms
第五章 减治法
Decrease and Conquer
教学内容


减治法的一般方法及变种 插入排序 深度优先查找和广度优先查找 生成组合对象的算法 减常因子算法 减可变规模算法 要求
Johnson-Trotter 法生成排列

其实有的算法并不需要知道规模n-1的排列就可 以直接得到规模n的排列结果,Johnson-Trotter算法就 是其中一种。利用这一算法求得的排列序列还是相邻
序列变化最小的一个序列集合,也就是说下一个序列
与上一个序列仅仅交换了两个元素的位置 。
J-T方法举例
n/2) 子问题解 子问题解 原问题解
原问题解
例题1:课本123页第一题,摆渡的士兵。 解题:1、假设小孩与士兵在同一岸边 2、考虑起始情况,即士兵:1 孩子:2 和后续情况,士兵:2孩子:2 如图:

因此可以得到n个士兵时求解的公式如下: F(1) = 4 n=1 F(n) = F(n-1) + 4 n>1
6
29
7
31
Βιβλιοθήκη Baidu
8
35
9
38
10
42
11
46
12
49
13
52
low=1
设置初始区间
mid=7
high=13 查找区间为[1, 13] 取中点mid=7 比较r[7]与k,将查找调整到左半区
low=1 mid=3 low=1 high=2 mid=1 low=high=2 mid=2
high=6
查找区间为[1, 6] 取中点mid=3 比较 r[3]与k,将查找调整到左半区 查找区间为[1, 2] 取中点mid=1 比较r[1]与k,将查找调整到右半区 查找区间为[2, 2] 取中点mid=2 比较r[2]与k,查找成功,返回mid的位置2
生成幂集:减一算法

减一算法(实现 —— 自底向上,规模加一)
从空集开始,每次向已生成的每个子集中加入一个元素,如此继续, 直到所有 n 个元素都加入为止。
例:生成 A = { a1, a2, a3 } 全部子集
n 开始 { } 1→ { } { 1 } 2→ { } { 1 } { 2 } { 1, 2 } 子集(元素下标表示) 子集数 20=1 21=2 22=4
折半插入法 —— 组合利用减一法和减半法
子数组有序,用折半查找为插入元素在其中找到一个合适的位 置。 例题:在有序表{ 7, 14, 18, 21, 23, 29, 31, 35, 38, 42, 46, 49, 52 }中查找值为14的记录的过程如图所示。
折半查找
0 1
7
2
14
3
18
4
21
5
23
插入法生列排列

举例:求n=3的排列 方法:在n=2的排列中插入3,
在n=1的排列中插入2。 过程: 在 1 中从右到左插入2得到 12,21 在 12 中从右到左插入3得到 123,132,312 在 21 中从右到左插入3得到 213,231,321
于是得 {123,132,312,213,231,321}
插入排序效率分析

插入排序效率分析



Tworst (n) 1 i 1 2 ... ( n 1) n( n 1) ( n ) 2 i 1 j 0 i 1

输入规模:元素个数 n 基本操作:比较操作 A[ j ] > V 效率类别:输入 A 为升序,每次插入只需比较1次 —— 最佳效率 输入 A 为降序 —— 最差效率,其他 —— 平均效率 n 1 最佳效率:要插入 n-1个元素,共需比较 n-1 次(线性效率) Tbest ( n) 1 n 1 ( n) 也可据伪码计算: i 1 最差效率 对每个元素如第 i 个元素插入,从 j = i-1 比较到 j = 0,共 i 次比较, n 1 i n 1 即插入元素1A[ i ] 要与前面的全部元素都比较一次。 1 2
分治法和减治法区别
分治法是对分解的子问题分别求解,需要对子问 题的解进行合并,而减治法只对一个子问题求解, 并且不需要进行解的合并。应用减治法(例如减 半法)得到的算法通常具有如下递推式:
0 T (n) T (n / 2) 1
n 1 n 1
5.1插入排序
简介


插入排序的过程类似玩牌时整理手中纸牌的过程。就 是对 n 个元素 A [ 0, ... , n-1 ] 排序的一种方法。它的 基本思想是:每步将一个待排序的对象按照其关键字 的大小,插到前面已经排好序的序列中的适当位置, 直到全部对象插入完毕为止。 常用的插入排序有:直接插入排序、折半插入排序、 链表插入排序和希尔排序,它们划分的依据是在排好 序的序列中寻找插入位置所使用方法的不同。
字典顺序生成排列

尽管Johnson-Trotter算法非常高效,但是似乎 不是那么直观,不太符合人们的思维习惯。事 实上比较自然的算法称为“字典排序( lexicographic order)算法”,它是根据单词在 字典中的排列顺序得到的算法。
字典生成顺序举例
例n=3 在{1,2,3}中按字典顺序选择: 123 132 213 231 312 321
3→ { } { 1 } { 2 } { 1, 2 } { 3 } { 1, 3 } { 2, 3 }{ 1, 2, 3 } 23=8
减治法生成幂集

例n=3 方法:在n=2的幂集中加入元素3,在n=1的幂集中 加入元素2

, {1} //n=1 , {1}, {2}, {1,2} //加入元素2 , {1}, {2}, {1,2}, {3}, {1,3}, {2,3}, {1,2,3}

5.4.2、生成幂集

生成幂集

幂集 n 元集合 A = { a1, a2, ... , an } 的全部子集组成的集合 0 1 2 n 子集个数:2n (数学) n n n n
C C C ... C 2n


应用举例 —— 0-1背包问题 找出 n 个物品中的最有价值子集,装入一个承重有限的背包中。 解背包问题的蛮力法要求:生成 n 个物品的全部组合 减一策略(用元素的下标表示) 设 { 1, 2, ..., n-1 } 问题已解决(规模-1),把 n 插入到每一个子集, 即得规模 n 的全部子集。与前述排列问题的减一策略的不同处: 排列问题在每个 { 1, ..., n-1 } 子集中插入元素 n 的位置有 n 个,组 合 问题仅 1 个插入位置。(为什么?) 解释:排列问题与元素在排列中的顺序有关,组合问题与顺序无关,

平均效率:比最差效率快2倍。若遇到基本有序数组,比选择排序 Tavg (n) n2 / 4 (n2 ) 和 冒泡排序的性能略优。
5.4 生成组合对象的算法 1、生成排列
排列问题指的是对于给定的多个元素求其 中各种可能的序列。为了简单起见,这里仅仅 考虑1到n之间的整数的排列问题。 下面介绍三种生成方法: (1)插入法 (2)Johnson-Trotter 法 (3)字典顺序法

掌握减治法的基本思想及在常见问题问题中的应用。
2
概念与算法策略

算法策略
减治法:利用给定规模与较小规模问题解之间的关系求解问题 的方法。 实现 —— 从顶向下:规模减小(递归) 从底向上:规模增大(非递归) 原问题(规模n) 减常量法:常量通常为1(每此迭代规模减小n→n-1 (规模n) 原问题 ) 减常因子法:常因子通常为 2(每此迭代规模减半n→ n/2 ) 减可变规模法:每次减去的规模不同 子问题(规模n-1) 子问题(规模

直接插入排序举例
待排序序列{89,45,68,90,29,34,17} 插入过程: InsertionSort ( A[0...n 1]) 89 45 {89} 不需比较 j V { {45,89} // 插入元素V 45 89 j for ( i 1 to n 1) do {45,68,89} 45 68 j i 89,90} {45,68, 1, V A[i ] {29,45,68, 0 and A[ j ] V ) while ( j 89,90} 45 68 {29,34,45,68 A[ 90} 后移 A[ j 1] 89, j ] // 29 45 {17,29,34,45,68, 89, 90} j j 1 插入次数=n-1=6 29 34 A[ j 1] V 比较次数=? 17 29 } // j 0 : 限位
图 折半查找成功情况下的查找过程
折半查找算法描述 1. low=1;high=n; //设置初始查找区间 2. 测试查找区间[low,high]是否存在,若不存 在,则查找失败;否则 3. 取中间点mid=(low+high)/2; 比较k与r[mid],有 以下三种情况: 3.1 若k<r[mid],则high=mid-1;查找在左半区 进行,转2; 3.2 若k>r[mid],则low=mid+1;查找在右半区 进行,转2; 3.3 若k=r[mid],则查找成功,返回记录在表中位 置mid;
5.1插入排序

插入排序

对 n 个元素 A [ 0, ... , n-1 ] 排序(非降序为例) 减一策略 —— 分析过程自顶向下(规模减小) 减去一个元素 A[n-1] , 对 A[ 0,...,n-2 ] 排序(非降序) 原问题的解 = 减一规模的解 + A[n-1] 对数组递归减一,分解到仅一个元素为止;再合并得到原问题解。 插入算法 —— 有三种方法,左右扫描称统称 直接插入法 左扫描:从左向右扫描有序子数组,遇到第一个≥A[n-1] 元素为止,在该元素前插入A[n1] . 若未找到,则插在最后。 右扫描:从右向左扫描有序子数组,遇到第一个≤A[n-1] 元素为止,在该元素后插入A[n1] . 若未找到,则插在最前。 常用:右扫描法。问:理由是什么? 理由:子数组若有等值元素,右扫描插入时需移动的元素个数少。 —— 它插在等值元素后,前面等值元素都不用移动位置

减一策略: 设规模减一 { 1, 2, ..., n-1 } 的全排列已解决,有 (n-1) ! 个 把 n 插入到这 (n-1) ! 个排列中去,就解决了规模 n 的问题,即得 { 1, ..., n } 全排列。在每个 { 1, ..., n-1 } 排列中插入 n 的位置有(n-1) + 1 = n 个, 排列数 = (n-1) ! ×n = n ! 问:这样得到的排列是唯一的吗? 答:是。(n-1) ! 个排列是唯一的,在其不同位置插入一个新元素 n, 结果
生成组合对象算法:生成排 列

生成组合对象
组合对象:满足一定约束条件的集合 组合数学:指出组合对象有多少个 —— 组合数(通常呈指数级增长) 如何生成:本节内容 生成排列 (前面讲过蛮力法)

生成集合元素
{ a1 , a2 , ..., an }
的全排列,可解释为:
—— 生成集合元素下标 { 1, 2, ..., n } 的全排列,排列数 = n ! 个
//加入元素3
降低规模的减治法可以用来求幂集。 减治法的缺点也是在求解规模为n的问题时,需要 得到规模为n-1的问题的解。这一过程是可以避免的, 使用位串法求解集合幂集就是其中的一种解决方案。

68 90 29 34 17
V
68 90 29 34 17
j V
89 90 29 34 17 89 90 29 34 17
j V
68 89 90 34 17
j V
45 68 89 90 17 34 45 68 89 90
j V
思考:为什么是右扫描插入V?
下划线为待插元素
插入排序算法与算例
相关文档
最新文档