排序算法(一)

news/发布时间2024/6/17 10:17:04

目录

一、插入排序

1.直接插入排序

(1)基本思想

(2)代码实现(升序)

(3)分析

2.希尔排序

(1)基本思想

(2)代码实现(升序)

(3)分析

二、选择排序

基本思想

1.简单选择排序

(1)代码实现(升序)

(2)分析

2.堆排序

(1)代码实现(升序)

(2)分析


排序是我们在程序中经常用到的算法之一,接下来的两篇博客就将对常见的排序算法进行总结、实现、评价。

在此之前,先补充一个概念——

稳定性:如果排序后原来关键字相同的元素的相对顺序不变,则称此排序算法是稳定的,否则不稳定。

一、插入排序

1.直接插入排序

(1)基本思想

把待排序的元素按照关键值的大小依次插入到一个已经有序的有序序列中,直到所有元素都插入完毕即可得到该组元素的有序序列。

(2)代码实现(升序)

void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end])  //{a[end + 1] = a[end];end--;}elsebreak;}a[end + 1] = tmp;}}

(3)分析

每次插入元素时,所需移动次数最少为0,最多为已经有序的元素个数(从0到n-1),因此该算法的时间复杂度为O\left ( n^{2} \right )

不需要额外的空间,空间复杂度为O\left ( 1 \right )

从上面代码可以看出,在进行大小比较时,如果相等,也会退出循环,不再继续移动元素,保证了二者的相对次序不变,因此该算法稳定。(当然,如果把<改为<=,这样算法依然可以实现排序功能,但是不稳定了。尽管如此,我们在实现该算法时还是可以让其成为稳定的,因此我们认为该算法是稳定的。下面的其他稳定性的算法与此同理。从中也可以看出,我们更希望一个排序算法是稳定的。)

元素集合越接近有序,直接插入排序的时间效率就越高。

2.希尔排序

(1)基本思想

选取一个整数gap,把所有元素分成gap组:相距gap的元素为一组,并对每组元素都进行直接插入排序。然后逐步缩小gap,重复上述操作,直到gap=1时,进行直接插入排序后便可得到有序序列。(如有疑问,请看分析部分)

(2)代码实现(升序)

关于gap的取法有很多种,本代码gap从n开始逐渐减半,直到gap=1结束。(不论gap怎么取,最终的gap必须等于1)

void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){gap /= 2;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;}elsebreak;}a[end + gap] = tmp;}}
}

(3)分析

既然最后一次也要全部进行直接插入排序,为什么还要提前进行多次的分组插入排序呢?直接插入排序的时间复杂度为O\left ( n^2 \right ),而且元素越无序,越接近n^2,元素越有序,越接近1。提前进行多次分组插入排序可以让元素的排列逐渐趋向有序,这样时间效率会越来越高,因此希尔排序的时间复杂度也会比直接插入排序小。可以说,希尔排序是对直接插入排序的优化。

那么希尔排序的时间复杂度是多少呢?这是一个复杂的问题,因为它的时间是所取距离gap的函数,这涉及一些数学上尚未解决的难题,经过大量的实验,目前认为希尔排序的时间复杂度约为O\left ( n^{1.3} \right )

不需要额外空间,空间复杂度为O\left ( 1 \right )

在分组插入排序的过程中,相同的元素可能分到不同的组别,进而导致各自排序后其相对次序可能改变,因此希尔排序不稳定。

二、选择排序

基本思想

每次从待排序的数据元素中挑选出最小或最大的一个元素,存放在序列的起始或末端位置,直到所有元素有序为止。

1.简单选择排序

该算法应该是C语言入门阶段就应该了解熟知的排序算法,不再过多介绍。

(1)代码实现(升序)

void Swap(int* x, int* y)
{int temp = *x;*x = *y;*y = temp;
}void SelectSort(int* a, int n)
{for (int i = 0; i < n-1; i++){int mini = i;for (int j = i + 1; j < n; j++){if (a[j] < a[mini])  //mini = j;}if (mini != i)Swap(a + i, a + mini);}
}

(2)分析

时间复杂度为O\left ( n^2 \right )

空间复杂度为O\left ( 1 \right )

该算法不稳定。

简单选择排序效率太低,实际中很少使用。

2.堆排序

堆排序是通过建堆来挑选最大或最小的元素的。升序建大堆,降序建小堆。有关堆的细节可以查看上篇博客【堆的实现及应用】。

(1)代码实现(升序)

void Swap(int* x, int* y)
{int temp = *x;*x = *y;*y = temp;
}void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] > a[child])  //{child++;}if (a[child] > a[parent])  //{Swap(a + child, a + parent);parent = child;child = child * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)
{for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}int index_end = n - 1;while (index_end > 0){Swap(a, a + index_end);AdjustDown(a, index_end, 0);index_end--;}
}

(2)分析

单次向下调整的时间复杂度为O(n),堆排序的时间复杂度为O\left ( n*log_{2}n \right )

不需要额外空间,空间复杂度为O\left ( 1 \right )

在建堆过程中相同的元素其相对次序会改变,堆排序不稳定

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

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

相关文章

unity学习(36)——角色选取界面(自制美工)

1.添加一个背景图片&#xff0c;记不住可以查之前的资料&#xff08;4&#xff09; 图片拖入asset&#xff0c;属性设成sprite&#xff1b;把图片拖到source image中&#xff1b;colour白色&#xff08;透明&#xff0c;点一下右边的笔即可&#xff09;&#xff1b;material为…

C++--Linux基础使用

文章目录 几个简单命令开机关机重启查看当前目录切换当前目录列出当前目录下的目录和文件列出指定目录下的目录和文件清屏查看/设置时间 目录和文件目录概要目录详细说明相对路径和绝对路径 上古神器vi创建/打开文件vi 的两种模式vi 的常用命令 用户管理组管理用户管理修改用户…

阿里云ECS香港服务器性能强大_安全可靠香港免备案服务器

阿里云香港服务器中国香港数据中心网络线路类型BGP多线精品&#xff0c;中国电信CN2高速网络高质量、大规格BGP带宽&#xff0c;运营商精品公网直连中国内地&#xff0c;时延更低&#xff0c;优化海外回中国内地流量的公网线路&#xff0c;可以提高国际业务访问质量。阿里云服务…

一文了解大数据生态

大数据一词最早指的是传统数据处理应用软件无法处理的过于庞大或过于复杂的数据集。 现在&#xff0c;对“大数据”一词的使用倾向于使用预测分析、用户行为分析或者其他一些从大数据中提取价值的高级数据分析方法&#xff0c;很少用于表示特定规模的数据集。 定义 大数据是…

typescript类型详解

因为介绍了ts的全部类型,所以比较长,各位可以通过目录选择性观看 typescript类型概述typescript 类型注解概念-->监测类型变化 ts类型注解语法ts常用类型原始类型对象类型对象类型_数组类型 ts新增,联合类型ts函数类型ts 函数类型 voidts 函数类型可选参数 ts 对象类型ts 可…

docker之安装mongo创建运行环境

目录 一、docker pull 最新资源 二、启动mongo镜像 启动命令查看日志拉取低版本镜像成功启动 三、进入mongo容器 进入容器进入mongo环境查询当前所在库切换库至admin随意切换库 并 创建用户登录用户新增文档数据等 五、总结 版本兼容可备份操作 一、docker pull 最新资源…

RK3588平台开发系列讲解(视频篇)ffmpeg 的移植

文章目录 一、ffmpeg 介绍二、ffmpeg 的组成三、ffmpeg 依赖库沉淀、分享、成长,让自己和他人都能有所收获!😄 📢ffmpeg 是一种多媒体音视频处理工具,具备视频采集功能、视频抓取图像、视频格式转换、给视频加水印并能将视频转化为流等诸多强大的功能。它采用 LGPL 或 G…

第39期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

【人工智能学习思维脉络导图】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 知识图谱1. 基础知识2.人工智能核心概念3.实践与应用4.持续学习与进展5.挑战与自我提升6.人脉网络 知识图谱 人工智能学习思维脉络导图 1. 基础知识 计算机科学基础数学基础&#xff08;线性代数、微积分、概率论和统计学…

7 数据迁移至达梦数据库

无论使用哪种解决方案很大可能性都需要进行数据迁移&#xff0c;即将旧的非 达梦数据库的数据迁移到达梦数据库。 我们要把 Nacos 的数据或者 SQL 语句迁移到达梦数据库。借助 DM 数据迁移工具 &#xff0c;完成 Nacos 配置数据表迁移到达梦数据库。

OLED示例程序、keil的调试模式

调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 Keil调试模式&#xff1a;借助Keil软件的调试模式&#xf…

Redis之缓存雪崩问题解决方案

文章目录 一、书接上文二、介绍三、解决方案1. 锁2. 不同的过期时间3. 缓存预热和定时任务 一、书接上文 Redis之缓存穿透问题解决方案实践SpringBoot3Docker 二、介绍 缓存雪崩&#xff0c;指大量的缓存失效&#xff0c;大量的请求又同时落在数据库。主要的一种诱因是key设…

限定时间地点|高级研究学者获批CSC赴奥地利访学

H老师拟申报CSC地方合作高级研究学者项目&#xff0c;并做了时间及地点的双限定&#xff1a;12天内获邀请函且限定在瑞士周边国家。最终我们提前2天完成任务&#xff0c;获得德国亚琛工业大学和奥地利克拉根福大学两个邀请函。通过对研究方向和地理位置的比较&#xff0c;H老师…

Python中处理HTTP异常和错误的策略

在Python中处理HTTP异常和错误是一项至关重要的任务&#xff0c;它关乎到应用程序的健壮性、用户体验以及数据的安全性。HTTP请求可能会遭遇多种异常和错误&#xff0c;如连接错误、超时、HTTP状态码错误等。为了有效地处理这些异常和错误&#xff0c;开发者需要采取一系列策略…

通过玩游戏学会AWS

游戏名字&#xff1a; Cloud Quest 类型&#xff1a;亚马逊云科技官方出了一款 3D 角色扮演、虚拟城市建造形式的游戏实验课 进入方法&#xff1a;浏览器搜索 Cloud Quest&#xff08;或扫描下方二维码&#xff09;进入 Cloud Quest 课程页。 选择以下的链接 点击进行注册 进…

基于SpringBoot的药品管理系统

基于SpringBoot的药品管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 药品详情 个人中心 员工界面 管理员界面 摘要 随着医疗技术的不断发展和人们健…

SpringBoot实战:打造企业资产管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

18年省赛蓝桥杯-等腰三角形

题目描述 本题目要求你在控制台输出一个由数字组成的等腰三角形。 具体的步骤是&#xff1a; 先用 1,2,3... 的自然数拼一个足够长的串 用这个串填充三角形的三条边。从上方顶点开始&#xff0c;逆时针填充。 比如&#xff0c;当三角形高度是 8 时&#xff0c;如下图&…

关于Linux中使用退格键出现^H的问题解决

关于Linux中使用退格键出现^H的问题解决 今天在Linux下执行脚本和监听端口的输入时候&#xff0c;不小心输错内容想要删除用退格键发现变成了^H&#xff0c;从网上查了资料并且实际应用了一下&#xff08;我的虚拟机是CentOS7&#xff09;。 使用ctrl退格键即可成功删除内容 …

机器学习面试:请你谈谈逻辑回归的用法?

逻辑回归可用于以下几个方面: (1)用于概率预测。用于可能性预测时&#xff0c;得到的结果有可比性。比如根据模型进而预测在不同的自变量情况下&#xff0c;发生某病或某种情况的概率有多大。 (2)用于分类。实际上跟预测有些类似&#xff0c;也是根据模型&#xff0c;判断某人属…
推荐文章