当前位置: 首页 > news >正文

常用排序算法总结

内容目录

  • 1. 选择类排序
    • 1.1 直接选择排序
    • 1.2 堆排序
  • 2. 交换类排序
    • 2.1 冒泡排序
    • 2.2 快速排序
  • 3. 插入类排序
    • 3.1 直接插入排序
    • 3.2 希尔排序
  • 4. 其它排序
    • 4.1 归并排序
    • 4.2 基数排序/桶排序

排序

在这里插入图片描述

在这里插入图片描述

1. 选择类排序

选择类排序的特征是每次从待排序集合中选择出一个最大值或者最小值。

1.1 直接选择排序

原理:两层循环,外层循环标记从哪开始遍历待排序数组,内层循环标记当前正在比较的元素。每次内层循环选出一个最小值/最大值。

ADL代码

在这里插入图片描述

复杂度

1.2 堆排序

原理:堆排序在逻辑上使用完全二叉树的结构,分为大顶堆小顶堆两类,即根结点为最大值的二叉树和根节点为最小值的二叉树。在物理结构上一般使用数组来实现完全二叉树。以大顶堆为例,对待排序数组进行排序主要需要完成两个操作:

  1. 在待排序数组上构造大顶堆。
  2. 从堆中取出最大值,并调整堆使其根节点仍然存储最大值。

可见,使用堆排序也是每次从待排序集合中选择一个最大或者最小值,因此其属于选择排序

在这里插入图片描述

那么该如何实现堆排序的这两个操作呢?

答案是:需要一个Restore操作负责:在其左右子树均已经为合法的堆的情况下,将以R为根的二叉树重建为堆

有了Restore操作之后,就可以完成初始化整个堆和从堆中选择最大值或者最小值的操作了:

  1. 初始化整个堆: 从结点floor(n/2)开始直到结点1依次遍历,对以每个结点为根的子树执行Restore操作。
  2. 从堆中选出一个最大值:将结点1与最后一个结点交换,堆的大小减一,对新的结点1执行Restore操作。

ADL代码

算法Restore(R, f, e. R)
/*R是存储完全二叉树的数组,索引从1开始;f是子树根节点索引;e是R中元素数量*/
R1.[初始化当前需要对比的子树的根]i <- f.
R2.[与左右子结点对比]// R[i]的右子结点就是R[2 * i + 1]// 左子节点就是R[2 * i]WHILE i <= e / 2 DO(IF 2 * i + 1 <= e AND R[2 * i + 1] > R[2 * i]child <- 2 * i + 1.ELSE child <- 2 * i.IF R[child] > R[i] THEN(R[child] <-> R[i].i <- child.)ELSE(BREAK.))|算法HeapSort(R, n. R)
/**/
H1.[初始化堆]FOR i = n/2 TO 1 STEP -1 DO(Restore(R, i, n. R).)
H2.[堆排序]e <- n.FOR j = n TO 2 STEP -1 DO(R[1] <-> R[j].e <- e - 1.Restore(R, 1, e. R).)|

复杂度:时间复杂度O(nlogn)。空间复杂度O(1)。不稳定。

2. 交换类排序

2.1 冒泡排序

原理:两层循环,外层循环标记待排序数组的最后一个元素下标e,内层循环负责比较当前元素i与其下一个元素j:

  • 如果i > j,交换i,j。
  • 如果i <= j,什么都不做。

这样内层循环遍历到e,此时e一定存储的是从1到e中的最大元素。

ADL代码:

在这里插入图片描述

扩展:看一下对冒泡排序的改进p237。改变了最好情况下的时间复杂度。

复杂度:O(n2)。O(1)。稳定。

2.2 快速排序

原理:快速排序基于一种自顶向下分治的思想,步骤如下:

  1. 如果待排序数组为空或者只剩下一个元素,直接返回
  2. 从待排序数组中任意选取一个元素,将比这个元素小的元素交换到数组的左边,比这个元素大的元素交换到数组的右边,这样就得到了两个子数组。
  3. 分别对两个子数组进行以上操作。

可以看到,这个算法适合使用递归来实现。

算法的关键问题和步骤在于:如何高效的把小的元素交换到右边,把大的元素交换到左边?

决定算法时间复杂度的步骤是:如何从待排序数组中选择一个元素,使其尽量把原数组划分为等长的子数组

扩展:看一下对快速排序的改进p244,使用随机数算法选取基准元素。

ADL代码

算法Partition(R, m, n. j)
/*负责从子数组[Rm, Rn]中选择一个基准元素,并把比它小的元素交换到数组的右边,比它大的元素交换到数组的左边。*返回值j是基准元素的下标。*/
P1.[选取一个基准元素]base <- R[m].
P2.[交换]left <- m + 1. right <- n.WHILE left < right DO(IF (R[left] > base && R[right] < base) THEN(R[left] <-> R[right].left <- left + 1.right <- right - 1.)	ELSE IF R[left] <= base THENleft <- left + 1.ELSEright <- right - 1.)
P3. [返回基准元素]IF R[left] > base(R[left - 1] <-> R[m].j <- left - 1.)ELSE(R[left] <-> R[m].j <- left.)|算法QSort(R, m, n. R)
Q1. [递归出口]
IF (m == n || m > n) RETURN.
Q2. [划分数组]Partition(R, m, n. j).
Q3. [递归]QSort(R, m, j - 1. R).Qsort(R, j + 1, n. R).|

复杂度

3. 插入类排序

3.1 直接插入排序

原理:两层循环,第一层循环标记前k个已经排好序的元素的下一个元素i,第二层循环将i插入到前k个元素中,使前k+1个元素有序。

ADL代码

在这里插入图片描述

复杂度:复杂O(n2),最好情况下下O(n)。空间O(1)

3.2 希尔排序

原理:直接插入排序的性能与待排序数组本身的**”有序度“高度相关,原数组越有序,时间复杂度就越接近O(n),原数组越无序,时间复杂度越接近O(n2)。特别是远距离的逆序对比近距离的逆序对会显著增加比较次数**。

例如,下面这个数组(2, 1)这个逆序对需要比较101次才能调整有序

[..., 0, 2, ...100个元素..., 1, ...]

而,下面这个数组(2, 1)这个逆序对只需要比较11次。

[..., 0, 2, ...10个元素..., 1, ...]

那么为了尽量减少原数组中远距离的逆序对,需要直接在大的步长的子数组中进行排序,

例如,假设原数组有1000个元素,那么可以先选取步长为100,将如下子数组单独进行直接插入排序

// 这里 子数组中的数字是下标而非元素的值
[1, 101, 201, ..., 901],
[2, 102, 202, ..., 902],
[3, 103, 203, ..., 903],
...
[100, 200, 300, ..., 1000]

之后逐步减少步长,然后进行排序,直到最后步长为1:

[1, 2, 3, ...,  1000]	// 退化为原始的直接插入排序

这样,最后原数组会完全有序。

ADL代码

在这里插入图片描述

4. 其它排序

4.1 归并排序

原理:类似快速排序,归并排序也利用了分而治之的思想,但是它是自底向上分治。步骤如下:

  1. 如果待排序的数组为空或者大小为1,直接返回
  2. 将数组从中间分开,对两个子数组分别进行以上操作
  3. 这时两个子数组已经有序,对两个子数组进行归并,然后返回

ADL代码

算法Merge(R, t, m, n. X)
/**/建立X。算法MSort(R, m, n. R)
/**/
M1.[递归出口]IF m == n OR m > n THENRETURN.
M2.[划分数组]mid <- (m + n) / 2.MSort(R, m, mid. R).Msort(R, mid + 1, n. R).
M3.[归并]Merge(R, m, mid, n. R).|

时间复杂度:O(nlogn)

4.2 基数排序/桶排序

不常考,了解即可。可能考简答题。

相关文章:

常用排序算法总结

内容目录 1. 选择类排序 1.1 直接选择排序1.2 堆排序 2. 交换类排序 2.1 冒泡排序2.2 快速排序 3. 插入类排序 3.1 直接插入排序3.2 希尔排序 4. 其它排序 4.1 归并排序4.2 基数排序/桶排序 排序 1. 选择类排序 选择类排序的特征是每次从待排序集合中选择出一个最大值或者最…...

[项目详解][boost搜索引擎#2] 建立index | 安装分词工具cppjieba | 实现倒排索引

目录 编写建立索引的模块 Index 1. 设计节点 2.基本结构 3.(难点) 构建索引 1. 构建正排索引&#xff08;BuildForwardIndex&#xff09; 2.❗构建倒排索引 3.1 cppjieba分词工具的安装和使用 3.2 引入cppjieba到项目中 倒排索引代码 本篇文章&#xff0c;我们将继续项…...

R语言编程

一、R语言在机器学习中的优势 R语言是一种广泛用于统计分析和数据可视化的编程语言,在机器学习领域也有诸多优势。 丰富的包:R拥有大量专门用于机器学习的包。例如,caret包是一个功能强大的机器学习工具包,它提供了统一的接口来训练和评估多种机器学习模型,如线性回归、决…...

Mysql主主互备配置

在现有运行的mysql环境下&#xff0c;修改相关配置项&#xff0c;完成主主互备模式的部署。 下面的配置说明中设置的mysql互备对应服务器IP为&#xff1a; 192.168.1.6 192.168.1.7 先检查UUID 在mysql的数据目录下&#xff0c;检查主备mysql的uuid&#xff08;如下的server-…...

如何预防数据打架?数据仓库如何保持指标数据一致性开发指南(持续更新)

大数据开发人员最经常遇到尴尬和麻烦的事是,指标开发好了,以为万事大吉了。被业务和运营发现这个指标在不同地方数据打架,显示不同的数值。为了保证指标数据一致性,要从整个开发流程做好。 目录 一、数据仓库架构规划 二、数据抽取与转换 三、数据存储管理 四、指标管…...

我谈Canny算子

在Canny算子的论文中&#xff0c;提出了好的边缘检测算子应满足三点&#xff1a;①检测错误率低——尽可能多地查找出图像中的实际边缘&#xff0c;边缘的误检率&#xff08;将边缘识别为非边缘&#xff09;低&#xff0c;且避免噪声产生虚假边缘&#xff08;将非边缘识别为边缘…...

算法的学习笔记—平衡二叉树(牛客JZ79)

&#x1f600;前言 在数据结构中&#xff0c;二叉树是一种重要的树形结构。平衡二叉树是一种特殊的二叉树&#xff0c;其特性是任何节点的左右子树高度差的绝对值不超过1。本文将介绍如何判断一棵给定的二叉树是否为平衡二叉树&#xff0c;重点关注算法的时间复杂度和空间复杂度…...

SSM学习day01 JS基础语法

一、JS基础语法 跟java有点像&#xff0c;但是不用注明数据类型 使用var去声明变量 特点1&#xff1a;var关键字声明变量&#xff0c;是为全局变量&#xff0c;作用域很大。在一个代码块中定义的变量&#xff0c;在其他代码块里也能使用 特点2&#xff1a;可以重复定义&#…...

kubeadm快速自动化部署k8s集群

目录 一、准备环境 二、安装docker--三台机器都操作 三、使用kubeadm部署Kubernetes 在所有节点安装kubeadm和kubelet、kubectl 配置启动kubelet(所有主机) master节点初始化 Mater重新完成初始化 执行Master初始化后的提示配置 配置使用网络插件 创建flannel网络 …...

解决JAVA使用@JsonProperty序列化出现字段重复问题(大写开头的字段重复序列化)

文章目录 引言I 解决方案方案1:使用JsonAutoDetect注解方案2:手动编写get方法,JsonProperty注解加到方法上。方案3:首字母改成小写的II 知识扩展:对象默认是怎样被序列化?引言 需求: JSON序列化时,使用@JsonProperty注解,将字段名序列化为首字母大写,兼容前端和第三方…...

分布式理论基础

文章目录 1、理论基础2、CAP定理1_一致性2_可用性3_分区容错性4_总结 3、BASE理论1_Basically Available&#xff08;基本可用&#xff09;2_Soft State&#xff08;软状态&#xff09;3_Eventually Consistent&#xff08;最终一致性&#xff09;4_总结 1、理论基础 在计算机…...

Java应用程序的测试覆盖率之设计与实现(二)-- jacoco agent

说在前面的话 要想获得测试覆盖率报告,第一步要做的是,采集覆盖率数据,并输入到tcp。 而本文便是介绍一种java应用程序部署下的推荐方式。 作为一种通用方案,首先不想对应用程序有所侵入,其次运维和管理方便。 正好,jacoco agent就是类似于pinpoint agent一样,都使用…...

【机器学习】13. 决策树

决策树的构造 策略&#xff1a;从上往下学习通过recursive divide-and-conquer process&#xff08;递归分治过程&#xff09; 首先选择最好的变量作为根节点&#xff0c;给每一个可能的变量值创造分支。然后将样本放进子集之中&#xff0c;从每个分支的节点拓展一个。最后&a…...

《a16z : 2024 年加密货币现状报告》解析

加密社 原文链接&#xff1a;State of Crypto 2024 - a16z crypto译者&#xff1a;AI翻译官&#xff0c;校对&#xff1a;翻译小组 当我们两年前第一次发布年度加密状态报告的时候&#xff0c;情况跟现在很不一样。那时候&#xff0c;加密货币还没成为政策制定者关心的大事。 比…...

Laravel 使用Simple QrCode 生成PNG遇到问题

最近因项目需求&#xff0c;需要对qrcode 进行一些简单修改&#xff0c;发现一些问题&#xff0c;顺便记录一下 目前最新的版本是4.2&#xff0c;在环境是 PHP8 &#xff0c;laravel11 的版本默认下载基本是4.0以上的 如下列代码 QrCode::format(png)->generate(test);这样…...

一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步

文章目录 1. 初识 Shell 解释器1.1 Shell 类型1.2 Shell 的父子关系 2. 编写第一个 Shell 脚本3. Shell 脚本语法3.1 脚本格式3.2 注释3.2.1 单行注释3.2.2 多行注释 3.3 Shell 变量3.3.1 系统预定义变量&#xff08;环境变量&#xff09;printenv 查看所有环境变量set 查看所有…...

批处理操作的优化

原来的代码 Override Transactional(rollbackFor Exception.class) public void batchAddQuestionsToBank(List<Long> questionIdList, Long questionBankId, User loginUser) {// 参数校验ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERR…...

机器视觉运动控制一体机在DELTA并联机械手视觉上下料应用

市场应用背景 DELTA并联机械手是由三个相同的支链所组成&#xff0c;每个支链包含一个转动关节和一个移动关节&#xff0c;具有结构紧凑、占地面积小、高速高灵活性等特点&#xff0c;可在有限的空间内进行高效的作业&#xff0c;广泛应用于柔性上下料、包装、分拣、装配等需要…...

RHCE-web篇

一.web服务器 Web 服务器是一种软件或硬件系统&#xff0c;用于接收、处理和响应来自客户端&#xff08;通常是浏览器&#xff09;的 HTTP 请求。它的主要功能是存储和提供网站内容&#xff0c;比如 HTML 页面、图像、视频等。 Web 服务器的主要功能 处理请求&#xf…...

Java - 人工智能;SpringAI

一、人工智能&#xff08;Artificial Intelligence&#xff0c;缩写为AI&#xff09; 人工智能&#xff08;Artificial Intelligence&#xff0c;缩写为AI&#xff09;是一门新的技术科学&#xff0c;旨在开发、研究用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...