选择排序
一:基本思想
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
解释:就是不断的找到最小的放在最左面,然后缩短数组,继续找最小的放在最左面,最后就是一个升序数组。
二:代码
单向选择排序:
void SelectSort(int* a, int n)
{// 初始化begin为数组的第一个元素int begin = 0;// 当begin小于n-1时循环,即只要不是数组的最后一个元素,就继续排序while (begin < n - 1){// 假设当前begin位置的元素是最小的int mini = begin;// 从begin+1到数组最后一个元素之间查找真正的最小元素for (int i = begin + 1; i <= n - 1; i++){// 如果找到一个比当前假设的最小元素还要小的元素,更新mini的值if (a[i] < a[mini]){mini = i;}}// 将找到的最小元素与begin位置的元素交换Swap(&a[mini], &a[begin]);// 交换完成后,begin位置的元素已经是正确的元素,将begin向后移动一位begin++;}
}
解释:
1:n是元素的个数,n-1是元素下标的最大值,begin<n-1即代表begin最大能取到n-2,此时数组还剩2个元素,是最后一次查找,再往下一个数字不用查找了,所以begin < n - 1
2:缩短数组就是代码中的begin++,找到最小并且交换之后,begin向后移动一位,进入新一轮的查找
双向选择排序:
void SelectSort2(int* a, int n)
{// 初始化begin为数组的起始位置,end为数组的末尾位置int begin = 0;int end = n - 1;// 当begin小于end时,表示数组中还有元素未排序while (begin < end){// 初始化最小元素和最大元素的索引为beginint mini = begin;int maxi = begin;// 从begin+1到end遍历数组,寻找当前未排序部分的最小和最大元素for (int i = begin + 1; i <= end; i++){// 如果当前元素大于已知最大元素的值,更新最大元素的索引if (a[i] > a[maxi]){maxi = i;}// 如果当前元素小于已知最小元素的值,更新最小元素的索引if (a[i] < a[mini]){mini = i;}}// 将找到的最小元素交换到begin位置Swap(&a[mini], &a[begin]);// 如果最大元素的索引刚好是begin(此时begin位置的元素已经被最小元素替换了)// 那么需要更新最大元素的索引为mini(因为最小元素已经被交换到begin位置)if (maxi == begin){maxi = mini;}// 将找到的最大元素交换到end位置Swap(&a[maxi], &a[end]);// 缩小未排序部分的范围,end向左移动一位,begin向右移动一位end--;begin++;}
}
解释:
1:和第一种相比区别在于,它每次遍历数组的时候,不仅找最小,还要找最大,然后再通过交换,每次的遍历能确定两个元素的位置
2:在交换时,我们第一步Swap(&a[mini], &a[begin]);将找到的最小元素交换到begin位置,但是如果最大元素的索引刚好是begin(此时begin位置的元素已经被最小元素替换了),那么需要更新最大元素的索引为mini(因为最小元素已经被交换到begin位置),再将找到的最大元素交换到end位置才是正确的交换。
图示如下:
三:代码运行结果
对同一个十万个整形的数组进行选择排序
可以看出:两者相差不大,毕竟都是同一个量级的时间复杂度。
四:复杂度讲解
时间复杂度:
选择排序的时间复杂度在最好、最坏和平均情况下都是O(n^2)
解释:
- 第一轮需要比较n-1次(对于n个元素的数组)。
- 第二轮需要比较n-2次。
- …
- 最后一轮需要比较1次。 因此,总的比较次数是 (n-1) + (n-2) + … + 1 = n(n-1)/2,大O表示为O(n^2)。
空间复杂度
选择排序的空间复杂度是O(1)。
选择排序是在原地进行排序的,不需要额外的存储空间来存储数据。
五:两种选择排序的对比
单向选择排序和双向选择排序的时间复杂度在理论上是相同的,都是O(n^2)。这是因为两种排序算法都需要遍历整个未排序的部分来找到最小(或最大)的元素,并且在每一轮排序中,都需要进行一定数量的比较。
具体来说:
-
单向选择排序:在每一轮排序中,算法会找到未排序部分的最小(或最大)元素,并将其放到已排序部分的末尾。每轮排序需要进行n-i次比较,其中i是当前轮次的索引(从0开始)。因此,总的比较次数是 (n-1) + (n-2) + … + 1 = n(n-1)/2,这是O(n^2)的时间复杂度。
-
双向选择排序:在每一轮排序中,算法会同时找到未排序部分的最小和最大元素,并将它们分别放到已排序部分的末尾和开始。尽管每一轮可以处理两个元素,但每轮排序仍然需要遍历整个未排序的部分,因此每轮排序的比较次数与单向选择排序相似。总的比较次数同样是O(n^2)。
虽然双向选择排序在每一轮可以减少交换次数(可能只需要两次交换,而单向选择排序可能需要一次),但是比较次数并没有减少。因此,两种算法在时间复杂度上是等价的。
需要注意的是,尽管时间复杂度相同,双向选择排序在实际执行中可能会有更好的性能,因为它减少了交换次数,而交换操作通常比比较操作更耗时。然而,这种性能提升通常不足以改变算法的时间复杂度类别。
六:代码分享
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<assert.h>
void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");
}
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}
void SelectSort(int* a, int n)
{// 初始化begin为数组的第一个元素int begin = 0;// 当begin小于n-1时循环,即只要不是数组的最后一个元素,就继续排序while (begin < n - 1){// 假设当前begin位置的元素是最小的int mini = begin;// 从begin+1到数组最后一个元素之间查找真正的最小元素for (int i = begin + 1; i <= n - 1; i++){// 如果找到一个比当前假设的最小元素还要小的元素,更新mini的值if (a[i] < a[mini]){mini = i;}}// 将找到的最小元素与begin位置的元素交换Swap(&a[mini], &a[begin]);// 交换完成后,begin位置的元素已经是正确的元素,将begin向后移动一位begin++;}
}
void SelectSort2(int* a, int n)
{// 初始化begin为数组的起始位置,end为数组的末尾位置int begin = 0;int end = n - 1;// 当begin小于end时,表示数组中还有元素未排序while (begin < end){// 初始化最小元素和最大元素的索引为beginint mini = begin;int maxi = begin;// 从begin+1到end遍历数组,寻找当前未排序部分的最小和最大元素for (int i = begin + 1; i <= end; i++){// 如果当前元素大于已知最大元素的值,更新最大元素的索引if (a[i] > a[maxi]){maxi = i;}// 如果当前元素小于已知最小元素的值,更新最小元素的索引if (a[i] < a[mini]){mini = i;}}// 将找到的最小元素交换到begin位置Swap(&a[mini], &a[begin]);// 如果最大元素的索引刚好是begin(此时begin位置的元素已经被最小元素替换了)// 那么需要更新最大元素的索引为mini(因为最小元素已经被交换到begin位置)if (maxi == begin){maxi = mini;}// 将找到的最大元素交换到end位置Swap(&a[maxi], &a[end]);// 缩小未排序部分的范围,end向左移动一位,begin向右移动一位end--;begin++;}
}
void TestOP()
{//生成N个随机数srand(time(0));int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);assert(a1);assert(a2);for (int i = 0; i < N - 1; i++){a1[i] = rand();a2[i] = a1[i];}//clock函数计算排序函数运行的时间int begin1 = clock();SelectSort(a1, N);int end1 = clock();//clock函数计算排序函数运行的时间int begin2 = clock();SelectSort2(a2, N);int end2 = clock();printf("SelectSort:%d\n", end1 - begin1);printf("SelectSort2:%d\n", end2 - begin2);//释放空间free(a1);//释放空间free(a2);}
int main()
{//单向选择排序TestOP();return 0;
}
相关文章:

选择排序
一:基本思想 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 解释:就是不断的找到最小的放在最左面,然后缩短数组,…...

SQL数据库(MySQL)
一、在Ubuntu系统下安装MySQL数据库 1、更新软件源,在确保ubuntu系统能正常上网的情况下执行以下命令 sudo apt-get update 2、安装MySQL数据库及相关软件包 # 安装过程中设置root用户的密码 123456 sudo apt-get install mysql-server # 安装访问数据库的客…...

在MindSearch中使用SiliconCloud:全面指南**
随着硅基流动(SiliconFlow)提供的InternLM2.5-7B-Chat服务的免费开放,我们迎来了MindSearch部署的全新篇章。这一服务的免费提供,不仅极大地降低了部署门槛,还为MindSearch的使用者带来了纯CPU版本的便利。本文将为您详…...

C++(2)之Linux多线程服务端编程总结
C之Linux多线程服务端编程读书笔记 Author: Once Day Date: 2023年1月31日/2024年8月23日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: Linux实践…...

【AI视频】复刻抖音爆款AI数字人作品初体验
博客主页: [小ᶻZ࿆] 本文专栏: AI视频 | AI数字人 文章目录 💯前言💯抖音上的爆火AI数字人视频💯注册HeyGen账号💯复刻抖音爆款AI数字人💯最终生成效果💯小结 对比原视频效果:…...
Mysql 面试题总结
1. Mysql 数据库,隔离级别有哪几个? 在 MySQL 数据库中,事务的隔离级别决定了一个事务在执行期间对其他事务可见的数据变化情况。MySQL 支持 SQL 标准定义的四种隔离级别,从低到高依次为: 读未提交(READ U…...

stack - queue
1.容器适配器 (1) 什么是适配器? 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口 (2) STL标准库中stack和queue的底层结构 虽然stack和…...

微软九月补丁星期二发现了 79 个漏洞
微软将在2024 年 9 月补丁星期二修复 79 个漏洞。 微软有证据表明,发布的四个漏洞被野外利用和/或公开披露;所有四个漏洞均已在CISA KEV上列出。微软还在修补四个关键的远程代码执行 (RCE) 漏洞。 不同寻常的是,微软本月尚未修补任何浏览器…...

研1日记12
1. 改19->10 2. 学习数据不平衡问题 1. 欠采样 合并两个样本数据 两种方式 1. 按原分布比例划分。sklearn中train_test_split里,参数stratify含义解析_traintestsplit参数stratify-CSDN博客 3.刘二大人 卷积操作 待看论文: 刘老师指导:…...
Rocky Linux 9安装mysqlclient库报错的解决方法
环境 VMware Rocky Linux 9.4 MySQL 8.0 安装mysqlclient报错 yum install python3-devel pip3 install mysqlclient报错: Downloading http://mirrors.aliyun.com/pypi/packages/37/fb/d9a8f763c84f1e789c027af0ffc7dbf94c9a38db961484f253f0552cbb47/mysqlcli…...

Spring Boot母婴商城:安全、便捷、高效
2 相关技术 2.1 SSM框架介绍 本课题程序开发使用到的框架技术,英文名称缩写是SSM,在JavaWeb开发中使用的流行框架有SSH、SSM、SpringMVC等,作为一个课题程序采用SSH框架也可以,SSM框架也可以,SpringMVC也可以。SSH框架…...
php实现kafka
kafka类: <?phpclass b2c_kafka {public $broker_list;public $topic;public $group_id;protected $producer null;protected $consumer null;protected $receive_wait_time;protected $receive_wait_num;/*** 构造方法* param object app*/public function …...

YOLOv10改进系列,YOLOv10损失函数更换为Powerful-IoU(2024年最新IOU),助力高效涨点
改进前训练结果: 改进后的结果: 摘要 边界框回归(BBR)是目标检测中的核心任务之一,BBR损失函数显著影响其性能。然而,观察到现有基于IoU的损失函数存在不合理的惩罚因子,导致回归过程中锚框扩展,并显著减缓收敛速度。为了解决这个问题,深入分析了锚框扩展的原因。针…...
工具知识 | Linux 常用命令参考手册
目录 文件 查看文件内容 headtailcatnlmore 创建 touchmkdirmktemp 删除 rmrmdir 查找文件 findlocate lspwdwcchattrpastestatgrepsedcdcpmvopensourcetreelnfilesortuniqsplitvim 系统管理 nohupwatchpingwhichshutdownrebootuptimecrontabatunameifconfigwhereischmodlsofc…...
mysql 常用知识点总结
MySQL 是一种广泛使用的关系型数据库管理系统(RDBMS),它基于结构化查询语言(SQL)。了解 MySQL 的语法对数据库管理和操作非常重要。以下是 MySQL 语法的详细完整解释,涵盖基本概念、创建表、查询、修改数据…...
conda常用指令
1、查看conda版本 conda --version 2、更新conda conda update conda 3、查看conda环境信息 conda info 4、查看已有虚拟环境 conda info --envs conda info -e conda env list 5、创建新虚拟环境 conda create --name myenv python3.8 6、激活环境和退出环境 conda…...

前后端分离项目--下载功能
文章目录 不使用代理服务器blobblob构造函数通过FormData对象的getBlob方法创建Blob对象将Blob对象转换成UR 使用代理服务器 前后端分离项目中下载与其他接口的使用不同,一般下载不走node,不通过代理服务器,而是直接在前台发送请求࿰…...

PMP--一模--解题--81-90
文章目录 4.整合管理81、 [单选] 一位先前不活跃的干系人参与程度突然增加,这种意外的参与导致了一些变更请求。项目经理应该做什么? 4.整合管理82、 [单选] 公司的新产品系列将在两个月内发布,95%的项目任务均已完成。但是,管理层…...

计算机网络 --- 【2】计算机网络的组成、功能
目录 一、计算机网络的组成 1.1 从组成部分看 1.2 从工作方式看 1.3 从逻辑功能看 1.4 总结 二、计算机网络的功能 2.1 数据通信 2.2 资源共享编辑 2.3 分布式处理 2.4 提高可靠性 2.5 负载均衡 一、计算机网络的组成 1.1 从组成部分看 我们举例分析计算机网络从…...

『功能项目』切换职业技能面板【49】
我们打开上一篇48切换职业面板的项目, 本章要做的事情是制作第二职业法师技能面板、第三职业面板并且完成切换 双击打开Canvas进入预制体空间 复制三个技能栏面板 重命名 设置第一技能栏 设置第二职业技能栏 设置第三职业技能栏 修改脚本:ChangeProfess…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...