0103设计算法-算法基础-算法导论第三版

news2024/11/15 18:14:01

文章目录

    • 一、分治法
    • 二、分析分治算法
    • 结语

我们可以选择使用的算法设计技术有很多。插入排序使用了增量方法:在排序子数组 A [ 1 ⋯ j − 1 ] A[1\cdots j-1] A[1j1]后,将单个元素 A [ j ] A[j] A[j]插入子数组的适当位置,产生排序好的子数组 A [ 1 ⋯ j ] A[1\cdots j] A[1j]

下面我们学习称为“分治法”的设计方法。

一、分治法

许多有用的算法在结构上是递归的:为了解决一个问题,算法一次或者多次调用其自身以解决紧密相关的若干子问题。

这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题的解,然后在合并这些子问题的解来建立原问题的解。

分治模式在每层递归时都有三个步骤:

  1. 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。
  2. 解决这些子问题,递归地求解各子问题。然后,若子问题的规模足够小,则直接求解。
  3. 合并这些子问题的解成原问题的解。

归并排序算法完全遵循分治模式。直观上其操作如下:

  • 分解:分解待排序的n个元素的序列成各具有 n 2 \frac{n}{2} 2n个元素的两个子序列。
  • 解决:使用归并排序递归地排序两个子序列。
  • 合并:合并两个已排序的子序列以产生已排序的答案。

递归终止条件:当待排序的序列长度为1,递归“开始回升”,长度为1的每个序列都已排好序。

归并排序算法的关键操作是“合并”步骤中两个已排序序列的合并。我们通过一个辅助过程MERGE(A,p,q,r)来完成合并,其中A是一个数组,p、q和r是数组的下标,满足 p ≤ q < r p\le q\lt r pq<r。该过程假设子数组 A [ p ⋯ q ] 和 A [ q + 1 ⋯ r ] A[p\cdots q]和A[q+1\cdots r] A[pq]A[q+1r]以排好序。它合并这两个子数组形成单一的已排好序的子数组并代替当前的子数组 A [ p ⋯ r ] A[p\cdots r] A[pr]

过程MERGE需要 O ( n ) O(n) O(n)的时间,其中 n = r − p + 1 n=r-p+1 n=rp+1是待合并元素的总和。为避免在每个基本步骤必须检查是否有堆为空,我们在每个堆的底部放置一个哨兵,它包含一个特殊的值,用于简化代码。这里我们使用 ∞ \infty 作为哨兵值,它不可能为较小的值,除非两个堆都已显露出其哨兵值。下面的伪代码实现MERGE

MERGE(A,p,q,r)
1  n1=q-r+1
2  n2=r-q
3  let L[1...n1+1] and R[1...n2+1] be new arrays
4  for i = 1 to n1
5    L[i] = A[p+i-1]
6  for j = 1 to n2
7    R[j] = A[q+j]
8  L[n1+1]=无穷
9 R[n2+1]=无穷
10 i = 1
11 j = 1
12 for k = p to r
13   if L[i] <= R[j]
14     A[k] = l[i]
15     i = i + 1
16   else A[k] = R[j]
17     j = j + 1

我们需要证明第12~17行for循环的第一次迭代之前该循环不变式成立,该循环每次迭代保持该不变式,并且循环终止时,该不变式提供了一种有用的性质来证明正确性。

初始化:循环的第一次迭代之前,有 k = p k=p k=p,所以子数组 A [ p ⋯ k − 1 ] A[p\cdots k-1] A[pk1]为空。这个空的子数组包含L和R的 k = p = 0 k=p=0 k=p=0歌最小元素。又因为 i = j = 1 i=j=1 i=j=1,所以 L [ i ] 和 R [ j ] L[i]和R[j] L[i]R[j]都是各自所在数组中未被复制回数组A的最小元素。

保持:为了理解每次迭代都维持选好不变式,首选假设 L [ i ] ≤ R [ j ] L[i]\le R[j] L[i]R[j].这时, L [ i ] L[i] L[i]是未被复制回数组A的最小元素。因为 A [ p ⋯ k − 1 ] A[p\cdots k-1] A[pk1]包含 k − p k-p kp个最小元素,所以在第14行将 L [ i ] L[i] L[i]复制到 A [ k ] A[k] A[k]之后,子数组 A [ p ⋯ k ] A[p\cdots k] A[pk]将包含 k − p + 1 k-p+1 kp+1个最小子元素。增加k的值(在for循环中更新)和 i i i的值后,为下次迭代重新建立了该循环不变式。反之,若 L [ i ] > R [ j ] L[i]\gt R[j] L[i]>R[j],则第16~17行执行适当的操作来维持该循环不变式。

终止:终止时, k = r + 1 k=r+1 k=r+1。根据循环不变式,子数组 A [ p ⋯ k − 1 ] A[p\cdots k-1] A[pk1]就是 A [ p ⋯ r ] A[p\cdots r] A[pr]且按从小到大的顺序包含 L [ 1 ⋯ n 1 + 1 ] 和 R [ 1 ⋯ n 2 + 1 ] L[1\cdots n1+1]和R[1\cdots n2+1] L[1n1+1]R[1n2+1]中的 k − p = r − p + 1 k-p=r-p+1 kp=rp+1个最小的元素数组L和R一起包含 n 1 + n 2 + 2 = r − p + 3 n1+n2+2=r-p+3 n1+n2+2=rp+3个元素。处两个最大的元素以为,其他所有元素都已被复制回数组A,这两个最大的元素是哨兵。

过程MERGE的运行时间是 O ( n ) ,其中 n = r − p + 1 O(n),其中n=r-p+1 O(n),其中n=rp+1。第1-3行和第8-11行中的每行都需要常量时间,第4-7行的for循环需要 O ( n 1 + n 2 ) = O ( n ) O(n1+n2)=O(n) O(n1+n2)=O(n)的时间,第12-17行的for循环有n次迭代,每次迭代需要常量时间。

现在我们keyiBaby过程MERGE做为归并排序的一个子程序来用。下面的过程MERGE-SORT(A,p,r)排序子数组 A [ p ⋯ r ] A[p\cdots r] A[pr]中的元素。若 p ≥ r p\ge r pr,则该数组最多有1个元素,所以已经排好序。否则,分解步骤简单地计算一个下标q,将 A [ p ⋯ r ] A[p\cdots r] A[pr]分解成两个子数组 A [ p ⋯ q ] 和 A [ q + 1 ⋯ r ] A[p\cdots q]和A[q+1\cdots r] A[pq]A[q+1r],前者包含 ⌈ n 2 ⌉ \lceil \frac{n}{2}\rceil 2n个元素,后者包含 ⌈ n 2 ⌉ \lceil \frac{n}{2}\rceil 2n个元素。

MERGE-SORT(A,p,r)
1  if p < r
2    q=floor((p+r)/2)
3    MERGE-SORT(A,p,q)
4    MERGE_SORT(A,q+1,r)
5    MERGE(A,p,q,r)

为了排序整个序列 A ( A [ 1 ] , A [ 2 ] , ⋯   , A [ n ] ) A(A[1],A[2],\cdots,A[n]) A(A[1],A[2],,A[n]),我们执行初始调用MERGE-SORT(A,1,A.length),这里再次有 A . l e n g t h = n A.length=n A.length=n。下图索命了当n位2的幂时该操作的过程。

算法分为分解和合并两部分。

分解:把长度为n的序列分解为 n 2 \frac{n}{2} 2n的两个子序列,在把长度为 n 2 \frac{n}{2} 2n的子序列分解为 n 4 \frac{n}{4} 4n的子序列,直至子序列长度为1.

合并:合并只含1项的序列形成长度为2的排好序的序列,合并长度为2的序列形成长度为4的排好序的序列,依此下去,直到长度为 n 2 \frac{n}{2} 2n的两个序列被合并最终成都为n的排好序的序列。

在这里插入图片描述

二、分析分治算法

当一个算法包含对其自身的递归调用时,我们往往可以用递归方程或递归式来描述其运行时间,该方程根据在较小输入上的运行时间来描述在规模为n的问题上的总运行时间。然后,我们可以使用数学工具来求解该递归式并给出算法性能的界。

分治算法运行时间的递归式来自基本模式的三个步骤。如前所述,我们假设 T ( n ) T(n) T(n)是规模为n的一个问题的运行时间。若问题规模足够小,如对某个常量 c , n ≤ c c,n\le c c,nc,则直接求解需要常量时间,我们将其写作 O ( 1 ) O(1) O(1)。假设把原问题分解为 a a a个子问题,没个子问题的规模是原问题的 1 b \frac{1}{b} b1为了求解一个规模 n b \frac{n}{b} bn的子问题,需要 T ( n b ) T(\frac{n}{b}) T(bn)的时间,所以需要 a T ( n b ) aT(\frac{n}{b}) aT(bn)的时间求解a个子问题。如果分解问题成子问题需要时间D(n),合并子问题的解成原问题的解需要时间为C(n),那么得到递归式
T ( n ) = { O ( 1 ) , 若 n ≤ c a T ( n b ) + D ( n ) + C ( n ) 其他 T(n)=\begin{cases} O(1),若n\le c\\ aT(\frac{n}{b})+D(n)+C(n)\quad 其他 \end{cases} T(n)={O(1),ncaT(bn)+D(n)+C(n)其他

归并排序算法的分析

虽然MERGE-SORT的伪代码在运算的数量不是偶数时也能正常工作,但是,如果假定原问题规模是2的幂,那么基于递归式的分析将被简化。在第4章,我们将看到这个假设不影响递归式解的增长量级。

下面我们分析建立归并排序n个数的最坏情况下的运行时间T(n)的递归式。归并排序一个元素需要长时间。当有 n > 1 n\gt 1 n>1个元素时,我们分解运行时间如下:

分解:分解步骤仅仅计算子数组的中间位置,需要常量时间,因此,D(n)=O(1)。

解决:我们递归求解两个规模为 n 2 \frac{n}{2} 2n的子问题,运行时间为 2 T ( n 2 ) 2T(\frac{n}{2}) 2T(2n)

合并: 在一个具有n个元素的子数组上过程MERGE需要O(n)的时间,所以C(n)=O(n)。

把分析结果带入上述递归式,有
T ( n ) = { O ( 1 ) , 若 n = 1 2 T ( n 2 ) + O ( n ) , n > 1 T(n)=\begin{cases} O(1),若n = 1\\ 2T(\frac{n}{2})+O(n),n\gt 1 \end{cases} T(n)={O(1),n=12T(2n)+O(n)n>1
在第4章,我们将看到“主定理”,可以用改定理证明 T ( n ) = O ( n lg ⁡ n ) , 起咋 lg ⁡ n 代表 log ⁡ 2 n T(n)=O(n\lg n),起咋\lg n 代表\log_2 n T(n)=O(nlgn),起咋lgn代表log2n

因为对数函数比任何线性函数增长要慢,所以对足够大的输入,在最坏情况下,运行时间 O ( n lg ⁡ n ) O(n\lg n) O(nlgn)的归并排序将优于运行时间诶 O ( n 2 ) O(n^2) O(n2)的插入排序。

算法实现及优化(在输入规模小于某个阈值时,使用插入排序)见下面链接2.

结语

欢迎小伙伴一起学习交流,需要啥工具或者有啥问题随时联系我。

❓QQ:806797785

⭐️源代码地址:https://gitee.com/gaogzhen/algorithm

[1]算法导论(原书第三版)/(美)科尔曼(Cormen, T.H.)等著;殷建平等译 [M].北京:机械工业出版社,2013.1(2021.1重印).p16-22

[2]归并排序-排序-算法第四版[CP/OL]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1549106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java-获取1688网站商家信息----简单应用

1.下载google浏览器 注: 苹果电脑下载 旧版本google浏览器 点设置时会自动更新, (卸载重装),运行时版本和驱动不匹配会报错 第三方网站下载链接:旧版本(安装后老是提示更新,最新版本没有找到对应的驱动,不能更新它) Google Chrome 64bit OS X版_chrome浏览器,chrome插件,谷歌浏…

基于Springboot的疫情隔离酒店管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的疫情隔离酒店管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

完全二叉树的层序遍历[天梯赛]

文章目录 题目描述思路 题目描述 输入样例 8 91 71 2 34 10 15 55 18 输出样例 18 34 55 71 2 10 15 91思路 完全二叉树最后一层可以不满&#xff0c;但上面的每一层的节点数都是满的 后序遍历的顺序为"左右根"&#xff0c;我们可以用数组模拟完全二叉树&#xff0c;…

奶瓶哪个牌子的比较好?适合新生儿的奶瓶分享

每一位新手家长都要选购很多东西&#xff0c;而必备的无疑就是新生儿奶瓶了。如果你不知道要给宝宝选什么品牌的奶瓶好&#xff0c;不懂哪些材质符合安全无毒标准。那么收藏这篇文章就对了&#xff0c;作为一名测评博主&#xff0c;我近期测评了多款全网热议的奶瓶&#xff0c;…

【机器学习300问】54、如何找到有效的组合特征?

一、为什么需要去寻找有效的组合特征&#xff1f; 因为并不是所有的特征组合都会意义&#xff0c;都能带来价值。 例如在房价预测场景中&#xff0c;卧室数量和浴室数量的比值有意义&#xff0c;但房屋面积与建造年份相组合作为新的组合特征&#xff0c;可能就没有实际含义&…

面试经典150题【111-120】

文章目录 面试经典150题【111-120】67.二进制求和190.颠倒二进制位191.位1的个数136.只出现一次的数字137.只出现一次的数字II201.数字范围按位与5.最长回文子串97.交错字符串72.编辑距离221.最大正方形 面试经典150题【111-120】 六道位运算&#xff0c;四道二维dp 67.二进制…

[HackMyVM]靶场quick5

kali:192.168.56.104 靶机:192.168.56.134 端口扫描 # nmap 192.168.56.134 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-27 19:08 CST Nmap scan report for careers.quick.hmv (192.168.56.134) Host is up (0.000056s latency). Not shown: 998 closed tcp p…

Unity编辑器功能将AB资源文件生成MD5码

将路径Application.dataPath/ArtRes/AB/PC文件夹下所有的Ab包文件生成MD5吗&#xff0c;通过文件名 文件长度MD5‘|’的格式拼接成字符串写入到资源对比文件abCompareInfo.txt中。 将路径pathFile扥文件生成MD5码

C语言学习之环境搭建【建议收藏】

学生时代&#xff0c;我们一般使用的VC【Microsoft Visual C 2010&#xff08;学习版&#xff09;】进行学习&#xff0c;该篇博客主要记录如何安装VC&#xff0c;非常详细&#xff0c;适合入门的小白&#xff0c;奶妈级别安装教程&#xff0c;建议收藏。 准备好软件安装包&…

LeetCode刷题--- Dijkstra 求最短路径

首先是图的表示&#xff0c;邻接矩阵和邻接表。实现看代码 邻接矩阵&#xff1a;二维数组&#xff0c; matrix[a][b] 表示 从a可以指向b无向图而言&#xff0c; matrix[a][b]matrix[b][a]&#xff0c;比如可以定义matrix[a][b]1表示ab是连接的&#xff0c;matrix[a][b]0表示ab…

Docker进阶:Docker Swarm —弹性伸缩调整服务的副本数量

Docker进阶&#xff1a;Docker Swarm —弹性伸缩调整服务的副本数量 1、 创建一个Nginx服务&#xff08;Manager节点&#xff09;2、查看服务状态&#xff08;Manager节点&#xff09;3、测试访问&#xff08;Worker节点&#xff09;4、查看服务日志&#xff08;Manager节点&am…

有效三角形的个数【双指针】

1.优化版暴力求解 如果能构成三⻆形&#xff0c;需要满⾜任意两边之和要⼤于第三边。实际上只需让较⼩的两条边之和⼤于第三边即可。将原数组排序&#xff0c;从⼩到⼤枚举三元组&#xff0c;这样三层 for 循环枚举出的三元组只需判断较⼩的两条边之和是否⼤于第三边。 class…

2024/3/24周报

文章目录 摘要Abstract文献阅读题目引言创新点数据处理研究区域和数据缺失值处理水质相关分析 方法和模型LSTMAttention机制AT-LSTM模型 实验结果 深度学习transformer代码实现1 模型输入1.1 Embedding层1.2 位置编码 2 Encoder2.1 编码器2.2 编码器层2.3注意力机制2.4多头注意…

Sora那么牛,他的模型的成本会有多少呢?

Sora的训练需要大量的计算资源&#xff0c;估计需要4211-10528个 Nvidia H100 GPUs运行一个月。推理成本&#xff1a;一个Nvidia H100 GPU大约每小时能生成5分钟的视频。初期的Sora成本将非常高&#xff0c;肯定是不适合普通人来使用&#xff0c;所以目前OpenAI都是先找一些艺术…

AttributeError: ‘ImageDraw‘ object has no attribute ‘textsize‘

用python绘制词云图时&#xff0c;出现报错AttributeError: ImageDraw object has no attribute textsize&#xff0c;应当如何解决&#xff1f; - CSDN文库

TikTok养号怎么做?打破0播放的前提是做好这些

TikTok养号的重要性不必多少&#xff0c;不仅可以在创号初期保障账号安全&#xff0c;后期的账号流量也需要以前期养好账号为前提。下面就给大家分享如何养号的真实操作攻略&#xff01; 一、为什么要养号 &#xff08;1&#xff09;提高系统推荐精准度 系统不了解新账户人设…

基于单片机病房温度监测与呼叫系统设计

**单片机设计介绍&#xff0c;基于单片机病房温度监测与呼叫系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机病房温度监测与呼叫系统设计概要主要涵盖了通过单片机技术实现病房温度的实时监测以及病人呼叫功能…

如何应对Android面试官->进程通信如何注册与获取服务

前言 大家好&#xff0c;我是老A&#xff1b; 这个章节继续上一章节继续讲解&#xff0c;主要讲解下 java 层服务的注册与获取、线程池&#xff1b;我们基于 AMS 来看下 java 层是如何获取的&#xff1b; SystemServer SystemServer 的启动也是 main 函数&#xff0c;我们进入…

三、阅读器开发--4、阅读器目录、全文搜索功能开发

1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版&#xff0c;充满整个屏幕浮在阅读器上方&#xff0c;左侧为目录右侧为背景&#xff0c;目录下方包含一个tab&#xff0c;点击后会切换不同的内容&#xff0c;这里tab是目录、书签&#xff0c;这里可以通过如下的…

(原型与原型链)前端八股文修炼Day5

一 原型链的理解 原型链定义&#xff1a; 原型链是 JavaScript 中实现对象继承的关键机制之一&#xff0c;它是一种对象之间的关系&#xff0c;通过这种关系&#xff0c;一个对象可以继承另一个对象的属性和方法。 原型链的组成&#xff1a; 每个对象都有一个指向另一个对象的…