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

合集下载

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

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

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

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

计算机算法设计与分析

计算机算法设计与分析

计算机算法设计与分析计算机算法设计与分析在计算机科学领域扮演着重要的角色。

它是研究和开发高效算法的过程,以解决各种计算问题。

在本文中,我们将探讨算法设计与分析的基本原理、常见算法类型以及算法分析的重要性。

一、算法设计与分析的基本原理算法设计的目标是开发一种能够解决特定问题的步骤序列。

这些步骤应该是明确的、非歧义的,并且能够在有限的时间内产生预期的结果。

为了实现这一目标,算法设计需要考虑以下几个主要原理:1. 问题抽象:将实际问题转化为计算机能够理解和处理的抽象形式。

这涉及到定义输入和输出,以及建立问题的数学模型。

2. 分解与合成:将复杂问题分解为更简单的子问题,然后将子问题的解合并成原始问题的解。

这种分解与合成的过程可以提高算法的可读性和效率。

3. 数据结构选择:选择适当的数据结构来存储和操作问题的输入和输出。

不同的数据结构对于不同的问题具有不同的性能和效率。

4. 控制结构设计:设计算法控制结构,如循环、条件语句和递归等,以实现预期的计算过程。

二、常见的算法类型在算法设计与分析中,有各种各样的算法类型可供选择。

以下是一些常见的算法类型:1. 排序算法:排序算法用于按照一定的规则对数据进行排序。

常见的排序算法包括冒泡排序、插入排序、选择排序、归并排序和快速排序等。

2. 搜索算法:搜索算法用于查找指定数据的位置或者判断数据是否存在。

常见的搜索算法包括线性搜索、二分搜索和哈希搜索等。

3. 图算法:图算法用于处理图数据结构上的问题。

常见的图算法包括最短路径算法、最小生成树算法和拓扑排序算法等。

4. 动态规划算法:动态规划算法用于解决一些最优化问题,它通过将问题分解为子问题,并利用已解决的子问题的解来解决原始问题。

三、算法分析的重要性算法分析是评估算法性能和效率的过程,它对于算法设计与分析至关重要。

通过对算法进行分析,我们可以了解算法的时间复杂度、空间复杂度和性能边界等关键指标。

这些指标可以帮助我们选择最适合特定问题的算法,并预测算法在不同输入情况下的表现。

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