当前位置:文档之家› 计算机算法设计与分析基础(第五章减治法)

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

n/2) 子问题解 子问题解 原问题解
原问题解
例题1:课本123页第一题,摆渡的士兵。 解题:1、假设小孩与士兵在同一岸边 2、考虑起始情况,即士兵:1 孩子:2 和后续情况,士兵:2孩子:2 如图:

因此可以得到n个士兵时求解的公式如下: F(1) = 4 n=1 F(n) = F(n-1) + 4 n>1
生成幂集:减一算法

减一算法(实现 —— 自底向上,规模加一)
从空集开始,每次向已生成的每个子集中加入一个元素,如此继续, 直到所有 n 个元素都加入为止。
例:生成 A = { a1, a2, a3 } 全部子集
n 开始 { } 1→ { } { 1 } 2→ { } { 1 } { 2 } { 1, 2 } 子集(元素下标表示) 子集数 20=1 21=2 22=4
分治法和减治法区别
分治法是对分解的子问题分别求解,需要对子问 题的解进行合并,而减治法只对一个子问题求解, 并且不需要进行解的合并。应用减治法(例如减 半法)得到的算法通常具有如下递推式:
0 T (n) T (n / 2) 1
n 1 n 1
5.1插入排序
简介


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

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
概念与算法策略

算法策略
减治法:利用给定规模与较小规模问题解之间的关系求解问题 的方法。 实现 —— 从顶向下:规模减小(递归) 从底向上:规模增大(非递归) 原问题(规模n) 减常量法:常量通常为1(每此迭代规模减小n→n-1 (规模n) 原问题 ) 减常因子法:常因子通常为 2(每此迭代规模减半n→ n/2 ) 减可变规模法:每次减去的规模不同 子问题(规模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?
下划线为待插元素
插入排序算法与算例



在排列的每一分量上画一个箭头。 求最大的移动整数k,不断移动元素,直到没有元素 可移动为止,掉转所有大于k 的整数方向。 移动元素:如果分量k 的箭头指向一个相邻的较小 元素,则该分量在排列中是移动的。 例n=3,从123开始:
1 23 1 32 3 1 2 32 1 23 1 2 1 3

直接插入排序举例
待排序序列{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 : 限位
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] . 若未找到,则插在最前。 常用:右扫描法。问:理由是什么? 理由:子数组若有等值元素,右扫描插入时需移动的元素个数少。 —— 它插在等值元素后,前面等值元素都不用移动位置
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}
生成组合对象算法:生成排 列

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

生成集合元素
{ a1 , a2 , ..., an }
的全排列,可解释为:
—— 生成集合元素下标 { 1, 2, ..., n } 的全排列,排列数 = n ! 个

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


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

减一策略: 设规模减一 { 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, 结果
图 折半查找成功情况下的查找过程
折半查找算法描述 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;
字典顺序生成排列

尽管Johnson-Trotter算法非常高效,但是似乎 不是那么直观,不太符合人们的思维习惯。事 实上比较自然的算法称为“字典排序( lexicographic order)算法”,它是根据单词在 字典中的排列顺序得到的算法。
Байду номын сангаас
字典生成顺序举例
例n=3 在{1,2,3}中按字典顺序选择: 123 132 213 231 312 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
相关主题