算法设计与分析第5章减治法..

合集下载

算法设计与分析 第5章 减治策略和变治策略

算法设计与分析 第5章 减治策略和变治策略

元素的求解过程与n个元素求解过程的联系,使问题的求解直接通
过表达式来求解,从而简化问题的求解难度。
一般采用自顶向下的分析方法,但求解时往往采用自底向上的
求解过程。这也是递归的方法。
(2)减去一个常量因子
在规模中减去一个常量因子,使求解的规模成倍的缩小,从而
提高问题求解的效率。
(3)减去的规模可变。 根据求解过程的变化来确定每次规模减少的程度。 具体实例:
减治策略及变治策略
减治策略
利用一个问题给定实例的解与该问题较小实例的解之间的关系, 使原问题求解过程简化的方法称之为减治策略。 可利用递归或者非递归的方法进行问题的求解。一般分为三类: (1)减去一个常量。 也就是在求解过程中将原来的求解规模减小一个固定的常数,
比如原来有n个元素,通过减治之后,编程n-1个元素,并且建立n个
实例
将原始序列先转化成另一种存储形式,然后再进行排序以简化
排序算法,比如:
1、堆以及堆排序
2、平衡二叉树
此外,复杂问题简化以降低求解难度: 1、多项式求解:霍纳法则
2、进制之间的转换问题。
此外,还有一些具体问题的求解方法均可采用变治策略。
1、直接插入排序
2、拓扑排序
3、全排列问题
4、子集问题
变治策略
变治策略也就是将原始问题变换成更容易求解的实例,然后对变化
后的实例进行求解。
主要ቤተ መጻሕፍቲ ባይዱ如下类型:
(1)变换为同样问题的更简单的实例,也就是实例化简。
(2)变换为同样问题实例的不同形式,也成为改变表现。
(3)变换为不同问题的实例,使问题更易求解,成为问题简化。

《算法设计与分析》教案

《算法设计与分析》教案
for(int k=0;k<4;k++) cout<<m[k]<<" ";
cout<<endl;
}
}
}
}
}
2、数字全排列(使用STL)
#include<iostream>
#include<algorithm>
using namespace std;
const int n=4;
int main()
{
int a[4]={2,4,3,1};
if(l==r-1)
{ if(a[l]>a[r]) { max=a[l]; min=a[r]; }
else { max=a[r]; min=a[l]; }
return;
}
int m = (l+r)/2;
T max1,max2,min1,min2;
MaxMin(a, l, m, max1, min1);
例:在n个元素中找最大值和最小值(非递归程序)
template<class T>
void MaxMin(T a[], int n, T& max, T&min)
{
if(n==1) { max=min=a[0]; return; }
if(a[0]>a[1]) { max=a[0]; min=a[1]; }
{
if(k==m)
{#43;+) cout<<a[i]<<" ";
cout<<endl;
}
else
for(int i=k;i<=m;i++)

5-第五章 减治法

5-第五章 减治法

2.比较v和 A[x]
确定查找范围
5.6.3 二叉查找树的查找和插入
• 二叉查找树:左子树的值小于根顶点,右 子树大于根顶点。
小结
5.4 生成组台对象的算法
• 组合问题 1、计数 2、结构
组合问题
5.4.1 生成排列
用减一思想生成{1,2,…,n}所有排列。
Johnson-trotter算法
• 字典序---增序排队
5.4.2 生成子集
1、挤压序: 所 2、是否存在—种生成比特串的最小变化算法,使得每
一个比特串和它的直接前趋之间仅仅相差一 个比特 位。
n / 2 ,它要求找出这样一个元素,该元素比列表中的—半元素大,又比另—半元素
小。这个中间的值被称为中值,它在数理统计中是—个非常重要的量。
• 类似快速排序的分区做法
• 例
15 15
效率分析: 1)平均效率 2)最差效率
5.6.2 插值查找
插值查找用于有序数组,“插值”代替了折 半查找中的中间值 1.计算
• 最坏输入是一个严格递减的数组,这种输 入的比较次数是
• 最好的情况下(升序),在外部循环的每 次送代中,比较操作只执行一次
• 平均
5.2深度优先查找和广度忧先查找
• 什么叫图的遍历 从图的任意点出发沿着一些边访问图中的 所有顶点,且使每个顶点仅被访问一次,这就 叫图的遍历. • 我们来看一下图的遍历的两种方法: 1.深度优先搜索 2.广度优先搜索
第一种算法是深度优先查找的一个简单应用:执行一次DFS遍 历,并记住顶点变成死端(即退出遍历栈)的顺序。将该次序反过来 就得到了拓扑排序的一个解。
第二种算法基于减(减一)治技术的一个直 接实现:不断地做这样—件事,在余下的有向 图中求出一个源,它是一个没有输入边的顶点, 然后把它和所有从它出发的边都删除。

算法设计与分析部分算法伪代码

算法设计与分析部分算法伪代码

第三章 蛮力法1.选择排序SelectionSort(A[0..n-1])for i=0 to n-2 domin=ifor j=i+1 to n-1 doif A[j]<A[min]min=jswap A[i] and A[min]2.冒泡排序BubbleSort(A[0..n-1])// 输入:数组A,数组中的元素属于某偏序集// 输出:按升序排列的数组Afor i=0 to n-2 dofor j=0 to n-2-i doif A[j+1]<A[j] swap A[j] and A[j+1]3.改进的冒泡算法ALGORITHM BubbleSortImproved( A[0,…,n –1] )// 冒泡排序算法的改进// 输入:数组A,数组中的元素属于某偏序集// 输出:按升序排列的数组Afor i ← 0 to n – 2 doflag ← Truefor j ← 0 to n – 2 – i doif A[j+1] < A[j]swap(A[j], A[j+1])flag ← False// 如果在某一轮的比较中没有交换,则flag为True,算法结束returnif flag = True4. 顺序查找算法算法 SwquentialSearch2(A[0...n],k)//顺序查找算法的实现,它用了查找键来作限位器//输入:一个n个元素的数组A和一个查找键K//输出:第一个值等于K的元素的位置,如果找不到这样的元素就返回 -1A[n]<--ki<--0while A[i]!=K doi<--i+1if i<n return iElse return -15. 蛮力字符串匹配算法 BruteForceStringMatch(T[0...n-1],P[0...m-1])//该算法实现了蛮力字符串匹配代表一段文本//输入:一个n个字符的数组T[0...n-1]// 一个m个字符的数组P[0..m-1]代表一个模式//输出:如果查找成功的话,返回文本的第一个匹配字串中第一个字符的位置, // 否则返回-1For i<--0 to n-m doj<--0While j<m and P[j]=T[i+j]doj<--i+1If j=m return ireturn -1合并排序最差Θ(nlog2n)快速排序最优Θ(nlog2n)最差Θ(n2)平均Θ(1.38nlog2n)选择排序 Θ(n2)冒泡排序 Θ(n2)插入排序最差Θ(n2)最优 Θ(n)平均 Θ(n2)第四章 分治法合并排序算法 MergeSort(A[0..n-1] )排序 // 递归调用mergesort来对数组 A[0...n-1]// 输入:一个可排序数组A[0..n-1]// 输出:非降序排列的数组A[0..n-1]if n > 1n/2 -1]copy A[0.. n/2 -1] to B[0..n/2 -1]copy A[ n/2 ..n-1] to C[0..MergeSort( B )MergeSort( C )Merge( B,C,A )两个数组合并的算法算法 Merge(B[0..p-1],C[0..q-1],A[0..p+q-1])//将两个有序数组合并成一个有序的数组和C[0...q-1]//输入:两个有序数组B[0...p-1]//输出:A[0..p+q-1]中已经有序存放了B和C中的元素 i=0,j=0,k=0;while i<p and j<q do≤C[j]if B[i]A[k]=B[i], i=i+1elseA[k]=C[j], j=j+1k=k+1if i=pcopy C[j..q-1] to A[k..p+q-1]elsecopy B[i..p-1] to A[0..p+q-1]快速排序算法QuickSort(A[l..r])// 使用快速排序法对序列或者子序列排序或者序列本身A[0..n-1]// 输入:子序列A[l..r]// 输出:非递减序列Aif l < rs ← Partition( A[l..r] )QuickSort( A[l..s-1] )QuickSort( A[s+1..r] )//s是中轴元素/基准点,是数组分区位置的标志实现分区的算法Partition( A[l..r] )// 输入:子数组A[l..r]// 输出:分裂点/基准点pivot的位置p ← A[l]i ← l; j ← r+1repeat≥ prepeat i ←i + 1until A[i]≤ prepeat j ← j – 1 until A[j]swap( A[i], A[j] )≥ juntil iswap( A[i], A[j] )swap( A[l], A[j] )return j折半查找BinarySearch( A[0..n-1], k )// 输入:已排序大小为n的序列A,待搜索对象k// 输出:如果搜索成功,则返回k的位置,否则返回-1 l=0,r=n-1;While l≤rmid= (l+r)/2if k = A[mid] return midelse if k < A[mid] r=m-1else l=m+1return -1Strassen矩阵Strassen方法M1=A11(B12-B22)M2=(A11+A12)B22M3=(A21+A22)B11M4=A22(B21-B11)M5=(A11+A22)(B11+B22)M6=(A12-A22)(B21+B22)M7=(A11-A21)(B11+B12)第五章 减治法插入排序ALGORITHM InsertionSort( A[0..n-1] )// 对给定序列进行直接插入排序// 输入:大小为n的无序序列A// 输出:按非递减排列的序列Afor i ← 1 to n-1 dotemp ← A[i]j ← i-1while j ≥ 0 and A[j] > temp doA[j+1] ← A[j]j ← j –1A[j+1] ←temp深度优先查找算法 BFS(G)//实现给定图的深度优先查找遍历//输入:图G=<V,E>//输出:图G的顶点,按照被DFS遍历第一次访问到的先后次序,用连续的整数标记,将V中的每个顶点标记为0,表示还“未访问”count =0//记录这是第几个访问的节点标记为 unvisitedmark each vertex with 0//∈ V dofor each vertex vif v is marked with 0dfs(v)dfs(v)//递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值//根据遇到它们的先后顺序,给它们附上相应的数字count = count + 1mark v with countv dofor each vertexw adjacent toif w is marked with 0dfs(w)广度优先BFS(G)/实现给定图的深度优先查找遍历//输入:图G=<V,E>//输出:图G的顶点,按照被BFS遍历第一次访问到的先后次序,用连续的整数标记,将V中的每个顶点标记为0,表示还“未访问”count =0mark each vertex with 0for each vertex v∈ V dobfs(v)bfs(v)//递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值//根据遇到它们的先后顺序,给它们附上相应的数字count = count + 1mark v with countinitialize queue with vwhile queue is not empty doa = front of queuefor each vertex w adjacent to a doif w is marked with 0count = count + 1mark w with countadd w to the end of the queueremove a from the front of the queue拓扑排序第六章 变治法Gauss消去法GaussElimination(A[1..n], b[1..n])// 输入:系数矩阵A及常数项 b// 输出:方程组的增广矩阵等价的上三角矩阵for i=1 to n doA[i][n+1] =b[i]for j= i+1 to n dofor k = i to n+1 do– A[i][k]*A[j][i]/A[i][i]A[j][k] = A[j][k]堆排序堆排序主要包括两个步骤:对于给定的数组构造相应的堆。

算法分析与设计多媒体课件

算法分析与设计多媒体课件

很多算法的效率都取决于输入的组织
最坏情况: Cworst(n) – 对于规模为n的输入,最大的消 耗
最好情况: Cbest(n) –对于规模为n的输入,最小的消耗 平均情况: Cavg(n)–对于规模为n的输入,“平均”的消

基本操作执行的次数体现在典型输入中
不是最好最坏情况的平均
将规模n的实例划分为几种类型,同种实例所需要的基 本操作执行次数一样,然后我们得到或者假设各种输入 的概率分布,以推导出我们的平均次数
2021/3/31
算法设计与分析
17
输入规模与基本操作举例
问题
输入规模的度量
基本运算
在长度为n的列表中 列表节点数目,例如 n 按关键字查找
关键字比较
两个矩阵相乘
矩阵的维度或者元素的 个数
两个数相乘
对 于 给 定 的 数 n, 判 断是否为素数
n的大小(经常转化为 二进制表示,即为二进 制的位数)
f1(n) + f2(n) O(max{g1(n), g2(n)})
2021/3/31
算法设计与分析
32
使用极限比较增长次数
0 order of growth of T(n) < order of growth of g(n)
lim T(n)/g(n) =
n→∞
c > 0 order of growth of T(n) = order of growth of g(n)
Θ(g(n)):增长率与g(n)相同的一类函数f(n)
Ω(g(n)):增长至少与g(n)相同的一类函数f(n)
2021/3/31
算法设计与分析
27
Big-oh
成立的条件是对于足够大的n>n0,存在大于0的常数c ,使得以上图形满足,后面符号的两个条件相同

第 五 章 减治法

第 五 章 减治法
仅仅通过一次重量的比较,就可以判断伪币是否存在。
算 分 析 与 设 计
西南科技大学
金块问题
有一个老板有一袋金块。每个月将有两 名雇员会因其优异的表现分别被奖励一 个金块。按规矩,排名第一的雇员将得 到袋中最重的金块,排名最后的雇员将 得到袋中最轻的金块。如果每个月都有 新的金块周期性的加入袋中,则每个月 都必须找出最轻和最重的金块。假设有 一台比较重量的仪器,我们希望用最少 的比较次数找出最轻和最重的金块。
算 分 析 与 设 计
西南科技大学
直接插入排序实现方法
减一技术下,该方法遵循的思路是:假设对较 小数组 A[0..n-2]排序问题已经解决了,得到一 个大小为n-1的有序数组。然后将要排序的第n 个元素,插入到数组的适合位置上,得到大小 为n的有序数组 A[0..n-1]。伪代码如下: void InsertionSort(a[]) {for(i=1;i<n-1;i++) //从第二个记录起进行插入 for (j=i-1; j>=0;j--) if a[j+1]-(a[j]) < 0 Swap(a[j+1], a[j]); }
算 分 析 与 设 计
西南科技大学
俄式乘法☺ 俄式乘法☺
算法思想:两个A和B数相乘,把数A每 次除以2,直到为0为止,另一个数B则不 断加倍,若第数A未除尽时,则数B应加 上自己。 7×8的计算步骤: 7 8 3 16+ 8 1 32+ 16 + 8
算 分 析 与 设 计
西南科技大学
约瑟夫斯问题( 约瑟夫斯问题(一)
算 分 析 与 设 计
西南科技大学
减常数因子减治法
减常数因子减治法的一个 典型算法就是折半查找 (Bin_Search)。它搜索 一个排序好的数组,将查 找目标与数组的中间位置 的元素相比,比它大则递 归查找数组的左边,反之 亦然。这个每次迭代都将 问题减小为原来的1/2。 折半查找每次都消去一个 常数因子2,因此其时间 效率为O(logn)。

AA-chapter 5-01 减治法

AA-chapter 5-01 减治法

18
插入排序
• 常用的插入排序有:
– 直接插入排序 – 折半插入排序 – 链表插入排序 – 希尔排序
• 它们的区别只在于 它们的区别 如何在排好序的序列 如何在排好序的序列 中寻找插入的位置。
算法分析与设计 兰州大学信息学院
19
5.1 直接插入排序
ALGORITHM InsertionSort( A[0 A[0..n ..n-1] ) // 对给定序列进行直接插入排序 // 输入:大小为n的无序序列A // 输出:按非递减排列的序列A for i ← 1 to n-1 do //把A[i]插入到A[1 A[1..i ..i-1] temp ← A[i] j ← i -1 while j ≥ 0 and A[j] > temp do A[j+1 A[j+ 1] ← A[j] j ← j-1 A[j+1 A[j+ 1] ← temp
InsertionSort( A[0 InsertionSort( A[0..n ..n-1] ) // 对给定序列进行直接插入排序 // 输入:大小为n的无序序列A // 输出:按非递减排列的序列A for i ← 1 to n-1 do temp ← A[i A[i] j ← i-1 while j ≥ 0 and A[j] > temp do A[j+1 A[j+ 1] ← A[j] j ← j-1 A[j+1 A[j+ 1] ← temp
算法分析与设计 兰州大学信息学院
21
5.1 直接插入排序 实例 (蓝色代表已排好序)
89 | 45 68 90 29 34 17 45 89 | 68 90 29 34 17
InsertionSort( A[0 InsertionSort( A[0..n ..n-1] ) // 对给定序列进行直接插入排序 // 输入:大小为n的无序序列A // 输出:按非递减排列的序列A for i ← 1 to n-1 do temp ← A[i A[i] j ← i-1 while j ≥ 0 and A[j] > temp do A[j+1 A[j+ 1] ← A[j] j ← j-1 A[j+1 A[j+ 1] ← temp

算法设计与分析智慧树知到答案章节测试2023年山东交通学院

算法设计与分析智慧树知到答案章节测试2023年山东交通学院

第一章测试1.解决一个问题通常有多种方法。

若说一个算法“有效”是指( )A:这个算法能在人的反应时间内将问题解决B:(这个算法能在一定的时间和空间资源限制内将问题解决)和(这个算法比其他已知算法都更快地将问题解决)C:这个算法能在一定的时间和空间资源限制内将问题解决D:这个算法比其他已知算法都更快地将问题解决答案:B2.农夫带着狼、羊、白菜从河的左岸到河的右岸,农夫每次只能带一样东西过河,而且,没有农夫看管,狼会吃羊,羊会吃白菜。

请问农夫能不能过去?()A:不一定B:不能过去C:能过去答案:C3.下述()不是是算法的描述方式。

A:自然语言B:程序设计语言C:E-R图D:伪代码答案:C4.有一个国家只有6元和7元两种纸币,如果你是央行行长,你会设置()为自动取款机的取款最低限额。

A:40B:42C:29D:30答案:D5.算法是一系列解决问题的明确指令。

()A:对B:错答案:A6.程序=数据结构+算法()A:错B:对答案:B7.同一个问题可以用不同的算法解决,同一个算法也可以解决不同的问题。

()A:错答案:B8.算法中的每一条指令不需有确切的含义,对于相同的输入不一定得到相同的输出。

( )A:错B:对答案:A9.可以用同样的方法证明算法的正确性与错误性 ( )A:对B:错答案:B10.求解2个数的最大公约数至少有3种方法。

( )A:错B:对答案:A11.没有好的算法,就编不出好的程序。

()A:对B:错答案:A12.算法与程序没有关系。

( )A:错B:对答案:A13.我将来不进行软件开发,所以学习算法没什么用。

( )A:对B:错答案:B14.gcd(m,n)=gcd(n,m m od n)并不是对每一对正整数(m,n)都成立。

( )A:错B:对答案:A15.既然程序设计语言可以描述算法,所以算法就是程序。

( )A:错B:对答案:A第二章测试1.并不是所有的算法,规模更大的输入需要更长的运行时间。

( )A:对答案:B2.算法效率分析框架主要关心一个算法的基本操作次数的增长次数,并把它作为算法效率的主要指标。

生成组合对象的算法(减治法)

生成组合对象的算法(减治法)

生成组合对象的算法(减治法)下面将详细介绍生成组合对象的减治法算法:1.定义问题:首先需要明确所要生成的组合对象的特征和属性。

例如,如果生成组合对象是包含固定数量的不同颜色的气球,那么问题的定义就是生成所有可能的气球颜色组合。

2.划分子问题:接下来,需要将问题划分为更小的子问题。

对于生成组合对象的问题,可以将其分解为生成单个组合对象的子问题。

在上述例子中,可以将其划分为生成单个气球颜色的子问题。

3.设计基本情况:在减治法中,需要定义一个基本情况,当问题的规模达到基本情况时,可以直接解决问题。

在上述例子中,当只有一个气球需要生成时,就可以直接生成所有可能的颜色。

4.减小问题规模:使用递归方法将问题规模逐渐减小。

在上述例子中,可以通过迭代每种颜色的气球来生成组合对象。

每次迭代,都解决一个气球颜色的子问题,并将其与其他已生成的气球组合。

5.合并子问题:将解决子问题的结果合并为整体解决方案。

在上述例子中,可以将每个气球颜色子问题的解合并为组合对象的解。

通过将每种颜色的气球与已生成的组合对象组合,可以生成所有可能的组合对象。

6.返回解决方案:最后,返回所有生成的组合对象作为最终的解决方案。

减治法的关键是确定如何划分子问题,并设计适当的方法来减小问题规模和合并子问题的解。

对于生成组合对象的问题,子问题的划分可以根据组合对象的特征和属性进行确定。

递归方法的使用可以确保问题规模不断减小,直到达到基本情况。

需要注意的是,生成组合对象可能会涉及到大量的计算和存储。

为了提高算法的效率,可以考虑使用剪枝等技术来减少不必要的计算和存储。

总结:生成组合对象的减治法算法通过将问题划分为较小的子问题,并逐步减小问题规模和合并子问题的解决方案来解决复杂问题。

这种算法的关键是确定子问题的划分和适当的规模减小和合并方法。

减治法是解决生成组合对象问题的一种有效方法,可以根据具体问题的特征和属性进行具体的实现。

算法设计与分析-第5章-减治法

算法设计与分析-第5章-减治法

0 T (n) T (n / 2) 1
n 1 n 1
所以,通常来说,应用减治法处理问题的效率是很高的, 一般是O(log2n)数量级。
5.2 查找问题中的减治法
5.2.1 折半查找 5.2.2 二叉查找树 5.2.3 选择问题
5.2.1
一、问题描述:
折半查找
应用折半查找方法在一个有序序列中查找值为k的记 录。若查找成功,返回记录k在序列中的位置,若查找失 败,返回失败信息。
low=1
பைடு நூலகம்
18>14
mid=3
mid=7 31>14 high=6
high=13
high=2
mid=1
7<14
low=2
mid=2
14=14
5.2.1 折半查找
三、算法设计
算法5.1——折半查找
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;
{ int data; //结点的值,假设查找集合的元素为整型
BiNode *lchild, *rchild; //指向左、右子树的指针 };
算法5.2——二叉排序树的查找
BiNode * SearchBST(BiNode *root, int k) { if (root= =NULL) return NULL; else if (root->data==k) return root; else if (k<root->data) return SearchBST(root->lchild, k); else return SearchBST(root->rchild, k); }

减治法

减治法

(2)插入法调整堆 关键问题是:在堆中插入一个结点,如何调整被插入结点, 使整个完全二叉树仍然是一个堆?
40 32 28 20 35 (a) 35与28交换 18 12 20 8 20 35 28 (b) 35与32交换 32 18 12 40 20 8 20 32 28 35 18 12 40 20 8
(c) 35<40调整完毕
假设当前堆中有k个结点,则要插入结点的编号为 k+1,插入法调整堆的算法如下:
算法4.5——插入法调整堆
1. 设i指向当前要插入的结点; 2. 若结点i是整个堆的根结点,则调整完毕; 3.否则,设j指向结点i的双亲结点;将结点i与结点j进行比较; 3.1 如果结点i的关键码小,则完全二叉树已经是堆,调整完毕; 3.2 否则将r[i]与r[j]交换;令i=j,转步骤2继续进行调整;
例:查找值为14的记录的过程: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
7 14 18 21 23 29 31 35 38 42 46 49 52 low=1
18>14
mid=3
mid=7 31>14 high=6
high=13
high=2 mid=1
7<14
low=2 mid=2
时间性能是O(logn)。
算法4.4——筛选法调整堆 void SiftHeap(int r[ ], int k, int n) { i=k; j=2*i; //置i为要筛的结点,j为i的左孩子 while (j<=n) //筛选还没有进行到叶子 { if (j<n && r[j]<r[j+1]) j++; //比较i的左右孩子,j为较于左右孩子中的较大者 break; else { r[i]←→r[j]; //将根结点与结点j交换 i=j; j=2*i; //被筛结点位于原来结点j的位置 } } }

算法设计与分析王红梅第1章绪论

算法设计与分析王红梅第1章绪论

2021/6/12
}
15
清华大学出版社
算法设计与分析
⑷ 伪代码——算法语言
伪代码(Pseudocode):介于自然语言和 程序设计语言之间的方法,它采用某一程序 设计语言的基本语法,操作指令可以结合自 然语言来设计。
优点:表达能力强,抽象性强,容易理解
使用方法:7 ± 2
2021/6/12
16
清华大学出版社
欧几里德算法
1. r = m % n; 2. 循环直到 r 等于0
2.1 m = n; 2.2 n = r; 2.3 r = m % n; 3. 输出 n ;
2021/6/12
算法设计与分析
17
清华大学出版社
算法设计与分析
1.1.4 算法设计的一般过程
1.理解问题
2.预测所有可能的输入
3. 在精确解和近似解间做选择
算法设计与分析
1.1 算法的基本概念
1.1.1 为什么要学习算法 1.1.2 算法及其重要特性 1.1.3 算法的描述方法 1.1.4 算法设计的一般过程 1.1.5 重要的问题类型
2021/6/12
5
清华大学出版社
算法设计与分析
1.1.1 为什么要学习算法
理由1:算法——程序的灵魂
➢ 问题的求解过程:
14
清华大学出版社
算法设计与分析
#include <iostream.h>
int CommonFactor(int m, int n)

{ int r=m % n;

while (r!=0)

{ m=n;

n=r;

r=m % n; }

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

算法设计与分析 王红梅 第二版 第5章_ 减治法
分别求中位数 10<13,结果在[10, 13]之间 长度为1,较小者为所求
舍弃13之前元素,{13,15} 舍弃15之后元素,{10,15}
{13,15} 舍弃13之后元素,{13} {13} {10,15} 舍弃10之前元素,{15} {15}
2015-5-2
第5章 减治法
Page 11
减治法的设计思想
算法5.1:两个序列中位数SearchMid 输入:两个长度为n的有序序列A和B 输出:序列A和B的中位数 1. 循环直到序列A和序列B均只有一个元素 1.1 a = 序列A的中位数; 1.2 b = 序列B的中位数; 1.3 比较a和b,执行下面三种情况之一: 1.3.1 若a=b,则返回a,算法结束; 1.3.2 若 a<b ,则在序列 A 中舍弃 a 之前的元素,在序列 B 中舍弃b之后的元素,转步骤1; 1.3.3 若a>b,则在序列A中舍弃a之后的元素,在序列B中 舍弃b之前的元素,转步骤1; 2. 序列A和序列B均只有一个元素,返回较小者;
2015-5-2
Reduce and Conquer Method
4
减治法的设计思想
减治法将问题划分为若干子问题,并且规模为n的 原问题的解与较小规模(通常是 n/2)的子问题的解之 间具有某种确定的关系:
(1)原问题的解只存在于其中一个较小规模的子问题中; (2)原问题的解与其中一个较小规模的解之间有某种对应关系。
二叉排序树的结点结构为: struct BiNode { int data; //结点的值,假设查找集合的元素为整型 BiNode *lchild, *rchild; //指向左、右子树的指针 };
算法5.2——二叉排序树的查找 BiNode * SearchBST(BiNode *root, int k) { if (root= =NULL) return NULL; else if (root->data==k) return root; else if (k<root->data) return SearchBST(root->lchild, k); else return SearchBST(root->rchild, k); }

减治法

减治法

第5章减治法(Decrease and Conquer)减治法的基本思想规模为n的原问题的解与较小规模(通常是n/2)的子问题的解之间具有关系:(1)原问题的解只存在于其中一个较小规模的子问题中;(2)原问题的解与其中一个较小规模的解之间存在某种对应关系。

由于原问题的解与较小规模的子问题的解之间存在这种关系,所以,只需求解其中一个较小规模的子问题就可以得到原问题的解。

2减治法的基本思想一旦建立了这种关系,就可以从顶至下(递归),也可以从底至上(非递归)的来运用Example, n!A top down (recursive) solutionA bottom up (iterative) solution3减治法的类型减治法有三种变种:1)减去一个常量2)减去一个常数因子3)减去的规模是可变的gcd(m, n)4减(一)治技术a problem of size nsubproblemof size n-1a solution to thesubprobleme.g., n!a solution tothe original problem5减(半) 治技术a problem of size nsubproblemof size n/2a solution to thesubprobleme.g., Binary searcha solution tothe original problem67典型的分治法subproblem 2 of size n /2subproblem 1 of size n /2a solution to subproblem 1 a solution to the original problema solution to subproblem 2a problem of size ne.g., mergesort减治与分治的区别考虑以下指数问题: 计算a n减一法Bottom-up: iterative (brute Force) Top-down:recursive分治法:减常因子法:a n= a*a*a*a*...*aa n= a n-1* a if n > 1= a if n = 1a n= a ⎣n/2 ⎦* a ⎡n/2⎤if n > 1= a if n = 1a n = (a n/2 ) 2if n is even and positive= (a(n-1)/2 ) 2 * a if n is odd and > 1 = a if n = 1O (log2n) O (n log2n)89111)2/(0)(>=⎩⎨⎧+=n n n T n T 所以,通常来说,应用减治法处理问题的效率是很高的,一般是O (log 2n)数量级。

减治法

减治法

第五章 减治法
5.4 生成组合对象的算法
方法:一开始从右往左的把 插入到 插入到12…(n-1)的位置中,然 的位置中, 方法:一开始从右往左的把n插入到 的位置中 后再调换方向从左往右把n插入到 插入到2…(n-1)中去。例如: 中去。 后再调换方向从左往右把 插入到 中去 例如:
开始 从右到左插入2 从右到左插入3 从左到右插入3 从右到左插入4 1 12 21 123 132 312 321 231 213 1234 1243 1423 4123 1324 1342 1432 4132 3124 3142 3412 4312 4321 3421 3241 3214 4231 2431 2341 2314 4213 2413 2143 2134
从左到右插入4
第五章 减治法
5.4 生成组合对象的算法
算法: 算法:JohnsonTrotter(n) //实现用来生成排列的 实现用来生成排列的Johnson-Trotter算法 实现用来生成排列的 算法 //输入:一个正整数 输入: 输入 一个正整数n //输出:{1,..,n}的所有排列的列表 输出: , , 的所有排列的列表 输出 ← ← ← ← 将排列初始化为 1 2 3 ... n While 存在移动元素 do 求最大的移动元素k 求最大的移动元素 将k和它所指向的元素互换 和它所指向的元素互换 调转所有大于k的元素的方向 调转所有大于 的元素的方向 将新排列加入到列表
Back
第五章 减治法
5.5 减可变规模算法
在减可变规模算法这种情况下,算法每次迭代的时候, 在减可变规模算法这种情况下,算法每次迭代的时候, 规模减小的模式都和另外依次迭代是不一样的。 规模减小的模式都和另外依次迭代是不一样的。计算最大公约 数的欧几里得算法是一个典型的例子。而别的实例还包括有: 数的欧几里得算法是一个典型的例子。而别的实例还包括有: 1、计算中值和选择问题 、 2、插值查找 、 3、二叉查找树的查找和插入 、 4、拈游戏 、

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

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

6
29
7
31
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
Johnson-Trotter 法生成排列

其实有的算法并不需要知道规模n-1的排列就可 以直接得到规模n的排列结果,Johnson-Trotter算法就 是其中一种。利用这一算法求得的排列序列还是相邻
序列变化最小的一个序列集合,也就是说下一个序列
与上一个序列仅仅交换了两个元素的位置 。
J-T方法举例

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

查找问题中的减治法——选择问题
问题描述:设无序序列T=(r1, r2, …, rn),T 的第k(1≤k≤n)小元素定义为T按升序排列 后在第k个位置上的元素。 给定一个序列T和一个整数k,寻找T的第k 小元素的问题称为选择问题)。 将寻找第n/2小元素的问题称为中值问题。
选择问题——想法
考虑快速排序的划分过程,一般情况下,设待划分的序列 为ri~rj,选定一个轴值对序列ri~rj进行划分,使得比轴值 小的元素都位于轴值的左侧,比轴值大的元素都位于轴值 的右侧,假定轴值的最终位置是s,则: (1)若k=s,则rs就是第k小元素; (2)若k<s,则第k小元素一定在序列ri ~ rs-1中; (3)若k>s,则第k小元素一定在序列rs+1 ~ rj中; 无论哪种情况,或者已经得出结果,或者将选择问题的查 找区间减少一半(如果轴值恰好是序列的中值)。
考虑不是把硬则该硬币即为假币,输出对应的序 号,算法结束;
2. 计算3组的硬币个数num1、num2和num3; 3. add1 = 第1组硬币的重量和;add2 = 第2组硬币 的重量和;
4. 根据情况执行下述三种操作之一:
4.1 如果add1小于add2,则在第1组硬币中查找; 4.2 如果add1大于add2,则在第2组硬币中查找; 4.3 如果add1等于add2,则在第3组硬币中查找;
2一个简单的例子—两个序列的中位数
对于两个给定的序列A={11, 13, 15, 17, 19}, B={2, 4, 10, 15, 20},求序列A和B的中位数的过程。
步 骤 1 2 3 4 5 6 7 8 初始序列 分别求中位数 15>10,结果在[10, 15]之间 分别求中位数 13<15,结果在[11, 15]之间 分别求中位数 10<13,结果在[10, 13]之间 长度为1,较小者为所求 操作说明 序列A {11, 13, 15, 17, 19} {11, 13, 15, 17, 19} 序列B {2, 4, 10, 15, 20} {2, 4, 10, 15, 20}
1. 循环直到序列A和序列B均只有一个元素 1.1 a = 序列A的中位数; 1.2 b = 序列B的中位数; 1.3 比较a和b,执行下面三种情况之一: 1.3.1 若a=b,则返回a,算法结束; 1.3.2 若 a<b ,则在序列 A 中舍弃 a 之前的元素, 在序列B中舍弃b之后的元素,转步骤1; 1.3.3 若a>b,则在序列A中舍弃a之后的元素, 在序列B中舍弃b之前的元素,转步骤1; 2. 序列A和序列B均只有一个元素,返回较小者;
组合问题中的减治法——淘汰赛冠军问题
问题描述:假设有 n=2k个选手进行竞技淘 汰赛,最后决出冠军的选手,设计竞技淘 汰比赛的过程。
淘汰赛冠军问题——实例
淘汰赛冠军问题——算法
string Game(string r[ ], int n) { i=n; while (i>1) { i=i/2; for (j=0; j<i; j++) if (Comp(r[j+i], r[j])) r[j]=r[j+i]; } return r[0]; }
查找问题中的减治法——折半查找
问题描述:应用折半查找方法在一个有序序列中 查找值为k的记录。若查找成功,返回记录k在序 列中的位置,若查找失败,返回失败信息。
折半查找——想法
折半查找利用了记录序列有序的特点,其查找过程是:取 有序序列的中间记录作为比较对象,若给定值与中间记录 相等,则查找成功;若给定值小于中间记录,则在中间记 录的左半区继续查找;若给定值大于中间记录,则在中间 记录的右半区继续查找。不断重复上述过程,直到查找成 功,或所查找的区域无记录,查找失败。
problem’s instance
or Another representation or another problem’s instance
solution
减治是基于变治的思想。
1 减治法的设计思想
(1) 原问题的 解只存在于其中 一个较小规模的 子问题中; (2) 原问题的 解与其中一个较 小规模的解之间 存在某种确定的 对应关系。
第五章
1 2 3 4 5
减 治 法
减治法的设计思想 查找问题中的减治法 排序问题中的减治法 组合问题中的减治法 小结
变 治 法 概 述
变治法分两个阶段工作,即“变”阶段和“治” 阶段. 逻 变治法的三种类型: 辑 1)实例化简(instance simplification) 等 2)改变表现(representation change) 价 3)问题化简(problem simpler reduction) instance
查找问题中的减治法——二叉查找树
在一个无序序列中执行查找操作,可以 将无序序列建立一棵二叉查找树,然后 在二叉查找树中查找值为k的记录,若查 找成功,返回记录k的存储地址,若查找 失败,返回空指针。
二叉查找树定义?
二叉查找树查找——想法
由二叉查找树的定义,在二叉查找树root中查找 给定值k的过程是: ⑴若root是空树,则查找失败; ⑵若k=根结点的值,则查找成功; ⑶若k<根结点的值,则在root的左子树上查找; ⑷若k>根结点的值,则在root的右子树上查找; 上述过程一直持续到查找成功或者待查找的子树 为空,如果待查找的子树为空,则查找失败。
k i≤ k 2 i ki≤k2i+1

k i≥ k 2 i ki≥k2i+1
1≤i≤n/2
堆排序——想法
堆排序是利用堆(假设利用大根堆)的特性进行 排序的方法,其基本思想是:首先将待排序的记 录序列构造成一个堆,此时,堆顶记录是堆中所 有记录的最大者,将它从堆中移走(通常将堆顶 记录和堆中最后一个记录交换),然后将剩余记 录再调整成堆,这样又找出了次大记录,以此类 推,直到堆中只有一个记录为止。
堆排序——实例
28 25 36 18 32 16 25
28
32
36
18 16
36
28
36
32 18 16
25
28 18 16
32
25
堆排序——算法
1. 设置 i 和 j ,分别指向当前要筛选的结点和要筛 选结点的左孩子; 2. 若 ri 已是叶子,则筛选完毕;否则,比较要筛 选结点的左右孩子,并将 j 指向值较大的结点; 3. 将ri和rj进行比较,有以下两种情况: 3.1 如果ri > rj,则完全二叉树已经是堆,筛选 完毕; 3.2 否则将 ri 和 rj 交换;令 i=j ,转步骤 2 继续进 行筛选;
k
[ r1 … … … rmid-1 ] rmid [ rmid+1 … … … rn ]
如果k<rmid查找这里 如果k>rmid查找这里
(mid=(1+n)/2)
折半查找——实例
在有序表{ 7, 14, 18, 21, 23, 29, 31, 35, 38 }中查找值为18的 过程如下:
折半查找——算法
舍弃15之后元素, {11,13,15}
{11,13,15}
舍弃10之前元素, {10,15,20}
{10,15,20}
舍弃13之前元素,{13,15} 舍弃15之后元素,{10,15} {13,15} 舍弃13之后元素,{13} {13} {10,15} 舍弃10之前元素,{15} {15}
2一个简单的例子—两个序列的中位数
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;
组合问题中的减治法——假币问题
问题描述:在 n 枚外观相同的硬币中,有 一枚是假币,并且已知假币较轻。通过一 架来任意比较两组硬币,从而得知两组硬 币的重量是否相同,或者哪一组更轻一些, 假币问题要求设计一个高效的算法来检测 出这枚假币。
T(n)=O(log2n)
假币问题——想法
最自然的想法就是一分为二,也就是把n枚硬币 分成两组,每组有⌊n/2⌋枚硬币,如果n为奇数, 就留下一枚硬币,然后把两组硬币分别放到天平 的两端。如果两组硬币的重量相同,那么留下的 硬币就是假币;否则,用同样的方法对较轻的那 组硬币进行同样的处理,因为假币一定在较轻的 那组里。
二叉查找树=平衡二叉树?
二叉查找树查找——实例
在二叉查找树中查找关键字值为35,95的过程:
50 30 50
80
40 90 85 88 32 20
30
80
20
35 32
40
35 85
90
88
简述查找过程?
二叉查找树查找——算法
BiNode * SearchBST(BiNode *root, int k) { if (root= =NULL) return NULL; else if (root->data==k) return root; else if (k<root->data) return SearchBST(root->lchild, k); else return SearchBST(root->rchild, k); }
分治法设计思想?两者在时间复杂 度区别?
选择问题——实例
找第4小的元素过程:
以5为轴值划分序列 4<5,只在左侧查找
相关文档
最新文档