递归和排序算法的应用

news2025/2/25 9:12:57

一、递归常见问题和注意事项

1. 堆栈溢出;
2. 警惕重复运算:
可以使用一个数据结构(散列表)将已经计算过的f(k)保存起来,每当调用到f(k)时,先产看下是否已经求结果,从而避免重复计算。
3. 将递归代码修改为非递归代码

二、冒泡、插入、选择排序

时间复杂度都是O(n^2);
**稳定性:**原序列中相同值得元素,经过排序后前后顺序不变;
**原地排序:**空间复杂度O(1);

冒泡排序:每次便利剩余的全部找出剩余最小的值;
插入排序:前面是有序的,从后面序列拿出最前面的元素插入到前面有序队列中合适的位置。分为已排序空间未排序空间
选择排序:分为已排序空间未排序空间,从未排序空间找出最小值放入已排序空间的末尾;

插入排序相对于冒泡排序的优势?


冒泡排序中数据的交换操作:
if (a[j] > a[j+1]) { // 交换
   int tmp = a[j];
   a[j] = a[j+1];
   a[j+1] = tmp;
   flag = true;
}

插入排序中数据的移动操作:
if (a[j] > value) {
  a[j+1] = a[j];  // 数据移动
} else {
  break;
}

使用冒泡排序需要K次交换操作,每次交换需要3次赋值语句,所需时间为3*k,而插入排序只需要K个时间。

三、归并排序和快速排序

归并排序:先分解,再合并。将数组采用递归的思想从中间分解拆分,知道不能拆分,然后再将拆分的进行排序后合并,使用分治思想
归并排序可以使稳定排序
在这里插入图片描述


// 归并排序算法, A是数组,n表示数组大小
merge_sort(A, n) {
  merge_sort_c(A, 0, n-1)
}

// 递归调用函数
merge_sort_c(A, p, r) {
  // 递归终止条件
  if p >= r  then return

  // 取p到r之间的中间位置q
  q = (p+r) / 2
  // 分治递归
  merge_sort_c(A, p, q)
  merge_sort_c(A, q+1, r)
  // 将A[p...q]和A[q+1...r]合并为A[p...r]
  merge(A[p...r], A[p...q], A[q+1...r])
}

merge()函数伪代码,merge()函数可以借用哨兵编程简化。


merge(A[p...r], A[p...q], A[q+1...r]) {
  var i := p,j := q+1,k := 0 // 初始化变量i, j, k
  var tmp := new array[0...r-p] // 申请一个大小跟A[p...r]一样的临时数组
  while i<=q AND j<=r do {
    if A[i] <= A[j] {
      tmp[k++] = A[i++] // i++等于i:=i+1
    } else {
      tmp[k++] = A[j++]
    }
  }
  
  // 判断哪个子数组中有剩余的数据
  var start := i,end := q
  if j<=r then start := j, end:=r
  
  // 将剩余的数据拷贝到临时数组tmp
  while start <= end do {
    tmp[k++] = A[start++]
  }
  
  // 将tmp中的数组拷贝回A[p...r]
  for i:=0 to r-p do {
    A[p+i] = tmp[i]
  }
}

在merge()合并函数需要临时空间,所以空间复杂度为O(n)。

快速排序:
快速排序是由上到下处理问题,利用原地分区,所以空间复杂度是O(1),不是稳定的排序算法。快速排序重点是选择合适的pivot,否可有可能导致时间复杂度退化到O(n^2)
在这里插入图片描述


// 快速排序,A是数组,n表示数组的大小
quick_sort(A, n) {
  quick_sort_c(A, 0, n-1)
}
// 快速排序递归函数,p,r为下标
quick_sort_c(A, p, r) {
  if p >= r then return
  
  q = partition(A, p, r) // 获取分区点
  quick_sort_c(A, p, q-1)
  quick_sort_c(A, q+1, r)
}

partition()分区函数函数


partition(A, p, r) {
  pivot := A[r]
  i := p
  for j := p to r-1 do {
    if A[j] < pivot {
      swap A[i] with A[j]
      i := i+1
    }
  }
  swap A[i] with A[r]
  return i

四、排序的思考问题

1、现在有 10 个接口访问日志文件,每个日志文件大小约 300MB,每个文件里的日志都是按照时间戳从小到大排序的。希望将这 10 个较小的日志文件,合并为 1 个日志文件,合并之后的日志仍然按照时间戳从小到大排列。如果处理上述排序任务的机器内存只有 1GB,有什么好的解决思路,能“快速”地将这 10 个日志文件合并吗?

最大时间戳的最小值这一点很关键 保证了当前取出来的数据是未排序种全局最小的。
批量读取文件。
分阶段的快速排序。

先取得十个文件时间戳的最小值数组的最小值a,和最大值数组的最大值b。然后取mid=(a+b)/2,然后把每个文件按照mid分割,取所有前面部分之和,如果小于1g就可以读入内存快排生成中间文件,否则继续取时间戳的中间值分割文件,直到区间内文件之和小于1g。同理对所有区间都做同样处理。最终把生成的中间文件按照分割的时间区间的次序直接连起来即可。类似桶排序。

2、如何在O(n)时间复杂内查找无序数组第K大的元素?
利用快速排序的思想,数组下标和K进行比较。

3、如何根据年龄对100万用户进行排序?
利用桶排序。

五、空间复杂度为O(n)排序,桶排序、计数排序、基数排序

1、桶排序(Bucket sort)
在这里插入图片描述
适用于在外部排序,数据存储在磁盘中,数据量比较大,内存有限,无法将全部数据加载到内存进行排序。
重点是如何将数据均匀的划分到每个桶里面。

2、计数排序(Counting sort)
桶排序的特殊情况,当数据的范围较小时,例如高考成绩排序,有一组数据2,5,3,0,2,3,0,3,使用大小为6的桶C[6]:
在这里插入图片描述
在这里插入图片描述
3、基数排序(radix sort)
例如对十万个电话号码进行排序,借助与稳定的排序,从高位向低位开始进行排序,排序11次即可。但是有时候要排序的数据长度不是等长的,可以对位数不够的在后面补0。
基数排序对要排序的数据是有要求的,需要可以分割出独立的“位”来比较,且位之间有递进的关系,如果数据a的高位比数据b高位大,那剩下的就不用比较了。

六、如何实现一个通用、高效的排序算法?

快速排序如何优化:主要是找到合适的分区点,为了避免极端情况,可以采用三数取中,随机法

七、二分法

如何快速的定位出IP对应的省份地址?
如果IP和归属地的关系不经常更新,可以先按照IP大小关系进行排序,查找时根据二分法进行查找。

有重复值的有序序列中查找一地个大于某值的元素?

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

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

相关文章

【嵌入式Linux】5.Ubuntu 交叉编译工具链安装

前言 交叉编译器中“交叉”的意思就是在一个架构上编译另外一个架构的代码,相当于两种架构“交叉”起来了。 其基本特点是: 1、它肯定是一个 GCC 编译器。 2、这个 GCC 编译器是运行在 X86 架构的 PC 上的。 3、这个 GCC 编译器是编译 ARM 架构代码的,也就是编译出来的可…

MongoDB 的安装、启动与连接

MongoDB 的安装、启动与连接一、MongoDB Community Server1. 安装(1) 下载(2) 安装1) 解压2) 配置环境变量3) 配置数据库存放目录a. 创建b. 赋权2. 启动验证二、MongoDB Compass安装三、连接一、MongoDB Community Server 1. 安装 (1) 下载 官网下载安装 (2) 安装 1) 解压…

three.js之访问几何体数据与几何体的旋转平移

文章目录访问几何体数据简介例子BoxGeometryPlaneBufferGeometry旋转、缩放、平移变换注意专栏目录请点击 访问几何体数据 简介 一般我们在开发项目的时候&#xff0c;可能会加载外部模型&#xff0c;这个时候&#xff0c;我们就需要获取到几何体的顶点数据这个时候&#xff…

Kubernetes入门

文章目录1、K8s快速入门1&#xff09;简介2&#xff09;架构&#xff08;1&#xff09;整体主从方式&#xff08;2&#xff09;master节点架构&#xff08;3&#xff09;Node节点架构3&#xff09;概念4&#xff09;快速体验&#xff08;1&#xff09;安装minikube&#xff08;…

商城项目环境准备 — docker安装elasticsearch

文章目录一、操作系统虚拟内存设置为262144二、拉取elasticsearch镜像三、创建docker容器挂载的目录四、设置挂载文件访问权限五、启动elasticsearch六、访问一、操作系统虚拟内存设置为262144 原因&#xff1a;系统虚拟内存默认最大映射数为65530&#xff0c;无法满足ES系统要…

十万部冷知识:“梅西”是怎么炼成的

随着2022卡塔尔世界杯小组赛第二轮的打响&#xff0c;现在第一支确定被淘汰的队伍已经出现了&#xff0c;它就是东道主卡塔尔队。它也成了继南非世界杯以来&#xff0c;史上第二个小组赛出局的东道主。而在明天的凌晨3点C组的比赛中&#xff0c;广大球迷朋友们关注的阿根廷队也…

C/C++指针入门详解(一)

一、引言 指针是一个地址&#xff0c;这个地址不仅可以是变量的地址&#xff0c;也可以是其它数据结构的地址。为了方便调用这个地址&#xff0c;C/C是通过指针变量来使用这个地址的。而我们常说的指针&#xff0c;其实在一定程度上说的是指针变量&#xff0c;但是我们必须清楚…

通用后台管理系统前端界面Ⅺ——信息列表页(弹窗复用增改、CRUD前端基础实现)

因为需求发生了点变化&#xff0c;所以把之前的代码稍改一下&#xff0c;把之前的信息列表全复制到用户列表中&#xff0c;最后效果一样。UserList.vue <template><div class"UserList"><!-- 查询、重置 --><el-form :inline"true" :…

UnityShader_基础理论

渲染流程 此处的渲染流程只是一个概念流水线。大概分为应用阶段、几何阶段、光栅化阶段。 应用阶段 主要输出渲染所需的几何信息&#xff0c;包括点、线、三角面等&#xff0c;传递给下一阶段使用&#xff1b;这一阶段主要CPU处理&#xff0c;该阶段产生的产物就是渲染图元…

【ML特征工程】第 6 章 :降维:用 PCA 压缩数据薄饼

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Java并发-synchronized使用方法

synchronized 关键字介绍 Java 中的每个对象都可以把它当作一个同步锁来使用&#xff0c;这些 Java 内置的使用者看不到的锁被称为内部锁&#xff0c;也叫作监视器锁。代码在进入 synchronized 代码块前会自动获取内部锁&#xff0c;这时候其他线程访问该同步代码块时会被阻塞…

十七、CANdelaStudio深入-创建新工程

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio创建新工程的过程,欢迎各位朋友订阅、评论…

别卷了!今年局势不一样开始裁员濒临失业

我被优化了&#xff0c;公司劳动合同都当天解除完&#xff0c;电脑也今天全部打包完&#xff0c;非常快&#xff0c;我也是惊呆了&#xff0c;刚刚和他们部门的人吃完饭&#xff0c;感觉今天就是一场梦&#xff0c;昨天还是催着做需求&#xff0c;今天说散就散”&#xff0c;前…

论文浅尝 | Efficient RDF graph storage based on RL

笔记整理&#xff1a;郑国鹏&#xff0c;天津大学硕士链接&#xff1a;https://link.springer.com/article/10.1007/s11280-021-00919-x动机知识是人工智能的基石&#xff0c;它通常以RDF图的形式表示。各个领域的大规模RDF图对图数据管理提出了新的挑战。关系型数据库因其成熟…

Java8 Collectors.toMap() 的使用

目录一、简单介绍用法1&#xff1a;根据某一属性&#xff0c;对对象的实例或属性做映射用法2&#xff1a;根据某一属性&#xff0c;对对象集合进行去重二、Duplicate key 异常1&#xff09;异常重现&#xff1a;2&#xff09;异常截图&#xff1a;3&#xff09;异常说明&#x…

点云梯度下采样

点云下采样又称点云精简。 均匀网格下采样 均匀网格下采样法是建立在空间包围盒精简算法之上对散乱点云快速简化的一种算法&#xff0c;其基本思想为&#xff1a;根据点云数据的密度确定最小三维网格&#xff08;体素&#xff09;的边长为a∗b∗ca*b*ca∗b∗c&#xff0c;计算…

含电热联合系统的微电网运行优化matlab程序(yalmip+cplex)(yalmip+gurobi)

含电热联合系统的微电网运行优化matlab程序&#xff08;yalmipcplex&#xff09;&#xff08;yalmipgurobi&#xff09; 参考文献&#xff1a;含电热联合系统的微电网运行优化 在当前能源互联网迅速发展及电热联系日渐紧密的环境下&#xff0c;提出基于电热联合调度的区域并网…

个人电影网站web网页设计制作—— 影视公司5页 DIV+CSS制作 浮动布局

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

【Vim】更改Vim编辑器的字体大小、改变字号;永久改变字号;改变字体颜色、字体显示样式

一、问题背景 初次使用Vim&#xff0c;由于电脑分辨率较高&#xff0c;在编辑器上显示的文本字号较小&#xff0c;不甚看清。 我使用的是Gvim for Windows。 二、网上的已有方法小结 2.1 快捷键ctrl 和ctrl - 标题中提到的号&#xff0c;需要按下shift才能输入&#xff0c…

用DIV+CSS技术设计的公益主题网站——防止电信诈骗(web前端网页制作课作业)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…