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

文章目录

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

我们可以选择使用的算法设计技术有很多。插入排序使用了增量方法:在排序子数组 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]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTPS协议的工作原理:保护网络通信的安全盾牌

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

深度分析鸿蒙应用开发的准确红利期、前景、未来发展方向

近年来&#xff0c;随着互联网技术的不断发展&#xff0c;鸿蒙生态开发逐渐成为热门话题。作为一种新兴的操作系统&#xff0c;其发展趋势备受关注。同时&#xff0c;鸿蒙生态开发的价值、就业岗位需求以及相关学习方面也引起了广泛关注。 那么就目前的形势来看&#xff0c;鸿…

【计算机网络篇】数据链路层(1)数据链路层的地位,问题

文章目录 &#x1f354;数据链路层在网络体系结构中的地位&#x1f354;链路&#xff0c;数据链路&#xff0c;帧&#x1f354;数据链路层的三个重要问题&#x1f95a;封装成帧和透明传输&#x1f95a;差错检测&#x1f95a;可靠传输 &#x1f354;数据链路层在网络体系结构中的…

C语言内存函数(1)【memcpy函数的使用与模拟实现】【memmove函数的使用和模拟实现】

关于内存函数有四个函数需要我们学习。分别是memcpy&#xff0c;memmove&#xff0c;memset和memcmp。都在头文件string.h里面。 一.memcpy函数的使用 一提到这个函数&#xff0c;我们可能会联想到strcpy函数&#xff0c;但strcpy函数是针对字符串的拷贝。但是我们在写代码的…

【2024第十二届“泰迪杯”数据挖掘挑战赛】B题基于多模态特征融合的图像文本检索—解题全流程(持续更新)

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛B题 解题全流程&#xff08;持续更新&#xff09; -----基于多模态特征融合的图像文本检索 一、写在前面&#xff1a; ​ 本题的全部资料打包为“全家桶”&#xff0c; “全家桶”包含&#xff1a;数据、代码、模型、结果csv、教程…

信号处理之快速傅里叶变换(FFT)

信号处理之快速傅里叶变换FFT 历史溯源欧拉公式傅里叶级数(FS)傅里叶变换(FT)离散傅里叶级数(DFS)离散时间傅里叶变换(DTFT)离散傅里叶变换(DFT)快速傅里叶变换(FFT)MATLAB中常用的FFT工具FFT中常见的问题 历史溯源 相信很多人知道傅里叶变换&#xff0c;但是很多人对傅里叶变…

React中 类组件 与 函数组件 的区别

类组件 与 函数组件 的区别 1. 类组件2. 函数组件HookuseStateuseEffectuseCallbackuseMemouseContextuseRef 3. 函数组件与类组件的区别3.1 表面差异3.2 最大不同原因 1. 类组件 在React中&#xff0c;类组件就是基于ES6语法&#xff0c;通过继承 React.component 得到的组件…

用Unidbg实现阿里系x-sign签名, 成功实现长x-mini-wua

本篇文章仅供学习讨论。 文章中涉及到的代码、实例&#xff0c;仅是个人日常学习研究的部分成果。 如有不当&#xff0c;请联系删除。 阿里系的签名算法&#xff0c;一直让人好奇的心痒痒。所以在空的时候&#xff0c;都会去扣其逻辑&#xff0c;一边学习逆向&#xff0c;一边学…

jmeter之接口功能自动化

一、接口测试简述 接口&#xff1a;用来连接前端&#xff0c;后端还有移动端的程序模块。由于不同端的工作进度不一样&#xff0c;需要对最开始出来的接口进行接口测试。 接口分类&#xff1a;POST&#xff0c;GET&#xff0c;PUT&#xff0c;DELETE。 POST请求的数据是放在…

极简自建web视频会议,私有云,rtmp/rtsp/webrtc一键参会直播会议互动方案

随着视频互动深入工作日常&#xff0c;很多客户需要自建一个会议&#xff0c;监控的交互平台&#xff0c;目前外面不管是开源还是非开源的平台&#xff0c;都是极为复杂&#xff0c;一般linux安装库关联部署复杂&#xff0c;非技术人员根本没办法使用&#xff0c;不方便集成部署…

基于springboot+vue的宠物商城网站

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

AAC相关知识

一、AAC音频格式种类有哪些 AAC音频格式是一种由MPEG-4标准定义的有损音频压缩格式。AAC包含两种封装格式 ADIF&#xff08;Audio Data Interchange Format音频数据交换格式&#xff09;和ADTS&#xff08;Audio Data transport Stream音频数据传输流&#xff09;。 ADIF 特点…

38 mars3d 对接地图图层 绘制点线面员

前言 这里主要是展示一下 mars3d 的一个基础的使用 主要是设计 接入地图服务器的 卫星地图, 普通的二维地图, 增加地区标记 基础绘制 点线面园 等等 测试用例 <template><div style"width: 1920px; height:1080px;"><div class"mars3dClas…

阿里云原生:如何熟悉一个系统

原文地址:https://mp.weixin.qq.com/s/J8eK-qRMkmHEQZ_dVts9aQ?poc_tokenHMA-_mWjfcDmGVW6hXX1xEDDvuJPE3pL9-8uSlyY 导读&#xff1a;本文总结了熟悉系统主要分三部分&#xff1a;业务学习、技术学习、实战。每部分会梳理一些在学习过程中需要解答的问题&#xff0c;这些问题…

Matlab|基于条件风险价值CVaR的微网动态定价与调度策略

目录 1 主要内容 模型示意图 电能交易流程 模型亮点 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序复现文章《A cooperative Stackelberg game based energy management considering price discrimination and risk assessment》&#xff0c;建立基于主从博弈的考虑…

神级工具之git (一): git 基操

一切都从&#xff1a;Git User Manual开始&#xff0c;或者中文版的Git中文手册 核心概念 工作区 工作区我们可见的&#xff0c;可以进行修改的目录树。我们可以在目录树中进行文件的查看&#xff0c;修改。通常我们会使用一个神级编辑器Vim。我给她取了个名字&#xff0c;就…

第十一届蓝桥杯大赛第二场省赛试题 CC++ 研究生组-子串分值和

solution1&#xff08;通过40%&#xff09; 依次求子串并统计出现过的字母个数 #include<iostream> #include<string> #include<set> using namespace std; int main(){string s, subs;cin >> s;int len s.size(), ans 0;for(int j 1; j < len…

Oracle Data Guard部署

Oracle的主备DG搭建 1. 修改主机名,同步时间 主库IP&#xff1a;192.168.100.137 备库IP&#xff1a;192.168.100.138配置主机名(主库) Hostname zygjpdb vim /etc/hosts 192.168.100.137 zygjpdb 192.168.100.138 zygjsdbvim /etc/sysconfig/network HOSTNAMEzygjpdb ------…

MySQL 排序的那些事儿

书接上回 上次发了几张图&#xff0c;给了几个MySQL Explain的场景&#xff0c;链接在这儿&#xff1a;你是不是MySQL老司机&#xff1f;来看看这些explain结果你能解释吗&#xff1f;MySQL 夺命6连问 我们依次来分析下这6个问题。 在分析之前&#xff0c;我们先来了解一下M…

(附源码)基于Spring Boot和Vue的智能订餐与外卖系统设计与实现

1. 引言 这部分通常包含了研究背景、研究意义、国内外研究现状、本文研究内容以及论文结构安排。 研究背景&#xff1a;介绍当前外卖市场的快速发展&#xff0c;以及智能订餐系统对改善人们生活的影响。研究意义&#xff1a;强调这类系统在现代生活中的作用和开发的创新点。国…