1.排序的概念及常见的排序算法

        排序在咱们日常生活中十分的常见,就好比是网上购物的时候通常能够选择按照什么排序,比如价格、评论数量、销量等。那么接下来咱们就来了解一些关于排序的概念。

        排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

        稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。

        内部排序:数据元素全部放在内存中的排序。

        外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。

        排序也是有很多算法的,一下是常见的排序算法:

        接下来咱们分别来说一说这些个常见的排序。

2.插入排序

        2.1直接插入排序

        插入排序就像是打扑克牌摸牌时的整理牌的动作,取出一张牌,插在两张牌之间形成升序,以此往复,直至牌被整理好。咱们再来观察一下直接插入排序排升序的动图模拟。

        首先,咱们来讨论开始情况,初始时,认为第一个元素已排好,①与②比较,如果②大,认为①②已经排好,接下来以②开始和③比较;如果②小,则取出②,①挪到②的位置,②向后没有数可以比较,②停在0的位置,认为①②排好,接下来以②开始和③比较。

        接下来,咱们假设一共有n个元素,设end为已排好的序列的最后一项的位置,提前存好end+1的内容赋值到tmp。end与end+1进行比较:

如果end+1比end要大,那么视为排好,end+1成为新的end继续与新的end+1进行比较

如果end+1比end要小,end的内容赋值到end+1中,这时候的end缺少数据,咱们假象tmp停在上面等待加入,接着end--,将end和tmp进行比较:

        ①如果tmp大于end,就说明前面的数据全都比tmp小,无需再比较,tmp停下比较,停在end+1的位置(end是--后的end)

        ②如果tmp小于end,那么end的值赋值在end+1的位置(tmp预备赋值的地方),想象tmp悬在end上方,end--,以此往复,直到end减到了-1,或者tmp碰到了比他小的数为止,最终tmp赋值在了end+1处。

        以上就是对于单趟排序的分析,以下是插入排序的具体内容,可见插入排序的时间复杂度是O(N^2).

void InsertSort(int* a, int n)
{for(int i=0;i<n-1;i++){//初始时,认为第一个数据已经排好int end = i;//提前存下end+1的内容int tmp = a[end + 1];//end为-1的时候结束while (end >= 0){//tmp小,还没有找到自己的位置if (tmp < a[end]){//end来到end+1的位置a[end + 1] = a[end];end--;}else//tmp大,说明已经找到位置了,不用继续遍历,退出循环{break;}}//将tmp赋值在end+1的位置a[end + 1] = tmp;}
}

        2.2希尔排序

        希尔排序是以插入排序为基础的一种排序,效率比直接排序更高,时间复杂度大概为O(N^1.3),其思想是:①通过预排序使数据趋于有序;②用插入排序排好。

        假设一个整型gap,那么预排序就是从0开始,每隔一个gap取一个数(不越界取),取完后进行一次插入排序,然后在从1开始,每隔一个gap取一个数,继续插入排序,直到取完,也就是把插入排序改成如下,gap的值可以为任意值(但是要小于元素个数)。

gap = 3;
for (int i = 0; i < n - gap; i++)
{int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;
}

        通过预排序,可以快速将前面较大的数据转移到后面。但仅有一个gap的,对数据的有序化有限,此时,就可以遍历gap的值来增强有序化,那么gap的初值选什么合适呢?gap值选大了就容易漏掉很多数据,取小了效率就低,于是有大佬研究,gap取元素个数的三分之一效率会较高。所以当元素个数为n时,gap=n,gap=n/3.

        都到这里了,肯定就有人发现了,当gap=1的时候不就是插入排序吗!那能不能把预排序和插入排序结合起来呢?可以是可以,但是咱们要确保gap的最后取值是1呀,于是对gap有了一点改进:gap=gap/3+1。一眼看上去可能看不出什么苗头,但是只要代值进去就会发现,gap最后都是1.

        那么最终的代码如下,

void TestShellSort(int* a, int n)
{int gap = n;while(gap>1){gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

3.选择排序

        3.1选择排序

        选择排序的思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

        以排升序,找小数为例,可以使用假设法找到小数下标,先设0为最小数,和1进行比较,如果0小,那么不变,如果1小,那么下标改为1,遍历一趟之后咱们就能将最小的值放在开头,单层循环结束后只需要重新设最小数就能完成排序,于是可以有以下代码,时间复杂度为O(N).

void SeSort(int* a, int n)
{int left = 0;while (left < n){int min = left;for (int i = left+1; i < n; i++){if (a[min] > a[i])min = i;}Swap(&a[min], &a[left]);left++;}
}

        此时提出一个问题,能不能同时找到最大值和最小值放到左右两边呢?这当然是可以的,但如果最大值位于最小值将要换到的地方或者是最小值位于最大值将要换到的地方呢?咱们需要注意这点,并在交换的时候注意更新数据。

void SelectSort(int* a, int n)
{int right = n-1;int left = 0;while(right>left){int max = left;int min = left;for (int i = left+1; i < n-left; i++){if (a[i] > a[max]){max = i;}if (a[i] < a[min]){min = i;}}Swap(&a[min], &a[left]);//如果重叠,那么更新数据if (max == left)max = min;Swap(&a[max], &a[right]);right--;left++;}
}

        3.2堆排序

        堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据需要注意的是排升序要建大堆排降序建小堆。其时间复杂度为O(nlogn)。

        在二叉树部分也有提过,其核心就是向下调整算法建堆,再将根与最后一个元素交换,调整堆的大小,在向下调整成新的堆,循环操作得到排好的数据。

        至于向下调整算法建堆可以参见往篇,而排序的过程也只是简单的控制定义域。

void AdjustDwon(int* a, int n, int root)
{//向下调整,大堆//root*2+1为孩子节点,如果孩子节点存在则循环继续while(root * 2 + 1<n){//找到两个孩子中大的那个int child = root * 2 + 1;if (child+1<n && a[child] < a[child + 1]){child = child + 1;}if (child<n && a[child] > a[root]){Swap(&a[child], &a[root]);}root = child;}
}void HeapSort(int* a, int n)
{//最后一个节点的父节点int parent = (n - 1 - 1) / 2;//向下调整建堆for (int i = parent; i >= 0; i--){AdjustDwon(a, n, i);}//选择,挑出大的数据for (int i = n - 1; i > 0; i--){Swap(&a[0], &a[i]);AdjustDwon(a, i - 1, 0);}
}

        今天的排序就到这里啦!至于剩下的排序就留到下篇吧!

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文献阅读笔记:RS电子战测试与测量技术文档

信息来源&#xff1a;罗德与施瓦茨&#xff08;Rohde & Schwarz&#xff09;公司关于电子战&#xff08;Electronic Warfare, EW&#xff09;测试与测量解决方案专业技术文档。 该文档由台湾地区应用工程师Mike Wu撰写&#xff0c;核心围绕电子战基础、雷达系统、实战应用及…

别再纠结 Postman 和 Apifox 了!这款开源神器让 API 测试更简单

别再纠结 Postman 和 Apifox 了&#xff01;这款开源神器让 API 测试更简单&#x1f525; 作为一名开发者&#xff0c;你是否还在为选择 API 测试工具而纠结&#xff1f;Postman 太重、Apifox 要联网、付费功能限制多&#xff1f;今天给大家推荐一款完全免费的开源替代方案 ——…

微调神器LLaMA-Factory官方保姆级教程来了,从环境搭建到模型训练评估全覆盖

1. 项目背景 开源大模型如LLaMA&#xff0c;Qwen&#xff0c;Baichuan等主要都是使用通用数据进行训练而来&#xff0c;其对于不同下游的使用场景和垂直领域的效果有待进一步提升&#xff0c;衍生出了微调训练相关的需求&#xff0c;包含预训练&#xff08;pt&#xff09;&…

创建其他服务器账号

✅ 在 /home74 下创建新用户的完整步骤1. 创建用户并指定 home 目录和 shellsudo useradd -m -d /home74/USERNAME -s /bin/bash USERNAME-m&#xff1a;自动创建目录并复制 /etc/skel 默认配置文件&#xff08;.bashrc 等&#xff09;。-d&#xff1a;指定用户 home 路径&…

【WebGIS】Vue3使用 VueLeaflet + 天地图 搭建地图可视化平台(基础用法)

初始化 创建项目 nodejs 18.0.6npm 9.5.1 引入地图服务 VueLeaflet GitHub - vue-leaflet/vue-leaflet&#xff1a; vue-leaflet 与 vue3 兼容 Vue Leaflet (vue2-leaflet) package.josn安装版本 直接添加四个依赖 {// ..."scripts": {// ...},"depen…

OpenCV 开发 -- 图像阈值处理

文章目录[toc]1 基本概念2 简单阈值处理cv2.threshold3 自适应阈值处理cv2.adaptiveThreshold更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;OpenCV开发 &#x1f448;1 基本概念 图像阈值处理&#xff08;Thresholding&#xff09;是图像处理中的一种基本技术…

单串口服务器-工业级串口联网解决方案

在工业自动化、智能电网、环境监测等领域&#xff0c;传统串口设备&#xff08;如PLC、传感器、仪表等&#xff09;的网络化升级需求日益增长。博为智能单串口服务器凭借高性能硬件架构、多协议支持和工业级可靠性&#xff0c;为RS485设备提供稳定、高效的TCP/IP网络接入能力&a…

第 9 篇:深入浅出学 Java 语言(JDK8 版)—— 吃透泛型机制,筑牢 Java 类型安全防线

简介&#xff1a;聚焦 Java 泛型这一“类型安全保障”核心技术&#xff0c;从泛型解决的核心痛点&#xff08;非泛型代码的运行时类型错误、强制类型转换冗余&#xff09;切入&#xff0c;详解泛型的本质&#xff08;参数化类型&#xff09;、核心用法&#xff08;泛型类/接口/…

MySQL和Redis的数据一致性问题与业界常见解法

一、为什么会出现数据不一致&#xff1f; 根本原因在于&#xff1a;这是一个涉及两个独立存储系统的数据更新操作&#xff0c;它无法被包装成一个原子操作&#xff08;分布式事务&#xff09;。更新数据库和更新缓存是两个独立的步骤&#xff0c;无论在代码中如何排列这两个步骤…

coolshell文章阅读摘抄

coolshell文章阅读摘抄打好基础学好英语限制你的不是其它人&#xff0c;也不是环境&#xff0c;而是自己Java打好基础 程序语言&#xff1a;语言的原理&#xff0c;类库的实现&#xff0c;编程技术&#xff08;并发、异步等&#xff09;&#xff0c;编程范式&#xff0c;设计模…

数据库造神计划第六天---增删改查(CRUD)(2)

&#x1f525;个人主页&#xff1a;寻星探路 &#x1f3ac;作者简介&#xff1a;Java研发方向学习者 &#x1f4d6;个人专栏&#xff1a;《从青铜到王者&#xff0c;就差这讲数据结构&#xff01;&#xff01;&#xff01;》、 《JAVA&#xff08;SE&#xff09;----如此简单&a…

使用Rust实现服务配置/注册中心

Conreg 使用 Rust 实现的配置与注册中心&#xff0c;参考了 Nacos 的设计&#xff0c;简单易用&#xff0c;使用 Raft 保证集群节点数据一致性。 支持的平台&#xff1a; UbuntuCentOS其他常见的 Linux 发行版&#xff08;我们使用 musl 编译&#xff0c;理论上支持所有主流…

三色标记算法

在 JVM 并发垃圾收集&#xff08;GC&#xff09;中&#xff0c;三色标记算法是实现 “GC 线程与用户线程并行执行” 的关键技术&#xff0c;它解决了并发场景下 “如何准确标记存活对象” 的核心问题&#xff0c;是 CMS、G1 等现代收集器的底层基础。一、三色标记的核心&#x…

OpenStack 管理与基础操作学习笔记(一):角色、用户及项目管理实践

OpenStack实验 OpenStack命令 admin-openrc.sh 进入管理员视图查看当前 OpenStack 中的项目列表&#xff0c;验证是否已经登录成功切换用户 修改文件切换用户上传文件切换用户OpenStack 认证管理 实验介绍 通过 OpenStack Dashboard 和 OpenStack CLI 两种方式创建角色、用户、…

直接查找试卷且可以免费下载

有什么网站可以直接查找试卷且可以免费下载&#xff1f; SearXNG开源元搜索引擎 This website shows the SearXNG public instances searx一个可定制的搜索引擎 分享一个基于Blockstack的DApp-searx,一个可定制的搜索引擎。 1- 链接 官网地址&#xff1a;https://searx.worl…

【独立版】智创云享知识付费小程序 v5.0.23+小程序 搭建教程

介绍智创云享知识付费小程序v5.0.23 含PC、小程序、H5 、前端&#xff0c;系统独立版已修复已知bug问题。框架是一款基于ThinkPHP框架开发的虚拟资源知识付费小程序&#xff0c;为广大创业者、自媒体及培训机构提供知识付费、内容付费、资源变现等领域的行业解决方案&#xff1…

布尔运算-区间dp

面试题 08.14. 布尔运算 - 力扣&#xff08;LeetCode&#xff09; Solution 这题的思路比较直接&#xff0c;就是枚举最后一个进行计算的运算符&#xff0c;但是在实现过程中需要注意&#xff0c;定义范式f(l,r)表示l到r范围&#xff0c;l和r必须为数字&#xff0c;l1,r-1为运…

MyBatis-Plus 扩展全局方法

1.文件内容package com.ruoyi.business.mybatisplus.base;import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.extension.service.IService;import java.util.List;/*** 扩展的 Service 接口* 所有自定义 Service 接口都需要继承此接口…

13.Linux OpenSSH 服务管理

文章目录Linux OpenSSH 服务管理环境准备OpenSSH 服务介绍SSH 介绍SSH 建立连接的过程加密类型双向加密过程使用 ssh 访问远端CLIssh 工具演示ssh工具配置文件配置 ssh 密钥认证ssh 故障模拟故障模拟排故故障自定义 SSH 服务配置文件禁止 root 登录禁止密码登录只允许特定用户登…

速通ACM省铜第五天 赋源码(MEX Count)

目录 引言&#xff1a; MEX Count 题意分析 逻辑梳理 代码实现 结语&#xff1a; 引言&#xff1a; 本来&#xff0c;今天我是想着出俩题或三题题解的&#xff0c;但是在打第一题的时候就天塌了&#xff0c;导致今天就只搓了一道题&#xff0c;这题的难度在CF中为1300的水准&…