【十大排序算法】选择排序

在这里插入图片描述

选择就像是在谱曲,每个决定就是一个音符,只有将它们有序地安排在一起,才能奏响美妙的乐章。

文章目录

  • 一、选择排序的思想
  • 二、选择排序的发展历程
  • 三、选择排序具象化
  • 四、选择排序算法实现
  • 五、选择排序的特性
  • 推荐阅读

一、选择排序的思想

选择排序(Selection Sort)是一种简单直观的排序算法。它的基本思想是,每次从待排序的数据元素中选择最小(或最大)的一个元素,放到已排序序列的末尾,直到所有元素均排序完毕。

这个过程可以用下面的步骤来描述:

  1. 首先,在待排序序列中找到最小(或最大)的元素,将其与序列中的第一个元素交换位置,这样最小(或最大)的元素就放到了序列的第一个位置。
  2. 然后,在剩余的未排序序列中,找到最小(或最大)的元素,将其与序列中的第二个元素交换位置,这样第二小(或第二大)的元素就放到了序列的第二个位置。
  3. 依此类推,重复以上步骤,直到所有元素都排序完毕。

选择排序的特点是简单直观,实现也比较容易,但是由于每次都要在剩余的未排序序列中查找最小(或最大)的元素,所以其时间复杂度较高,为 O ( n 2 ) O(n^2) O(n2)。因此,选择排序适用于数据量较小的情况。

二、选择排序的发展历程

选择排序是一种简单直观的排序算法,其发展历史可以追溯到 20 世纪初期。

  1. 早期方法:选择排序的基本思想可以追溯到早期的人工排序方法。在计算机出现之前,人们就已经使用手工方法对物品进行排序,例如根据尺寸或其他属性进行选择和排列。
  2. 算法形式化:选择排序的第一个严格定义可以追溯到 20 世纪 50 年代。这时,计算机科学家开始将排序算法形式化为算法和程序。选择排序作为最简单的排序算法之一,很快就被提出并研究。
  3. 早期计算机应用:随着计算机的发展,选择排序成为早期计算机应用中常用的排序算法之一。虽然它不是最有效的排序算法,但它的简单性和直观性使得它在早期的计算机系统中得到了广泛应用。

三、选择排序具象化

场景假设:我们需要将下图序列使用选择排序按从小到大进行排序。
workspace.png

  1. 1 1 1:在当前序列中找到最小的元素即 1 1 1 与第 1 1 1 个元素(即: 4 4 4)交换位置

workspace.png

  1. 2 2 2:在当前序列中找到最小的元素即 2 2 2 与第 2 2 2 个元素(即: 3 3 3)交换位置

workspace (1).png

  1. 3 3 3:在当前序列中找到最小的元素即 3 3 3 与第 3 3 3 个元素(即: 4 4 4)交换位置

workspace (2).png

  1. 4 4 4:在当前序列中找到最小的元素即 4 4 4 与第 4 4 4 个元素(即: 5 5 5)交换位置

workspace (3).png

  1. 5 5 5:不需要做任何操作,因为所有元素已排序好

workspace.png
我们可以发现:其实 n n n 个元素,只需要 n − 1 n - 1 n1 趟选择就可以完成排序。

四、选择排序算法实现

// 选择排序算法实现
public void selectionSort(int[] arr) {int n = arr.length; // 获取数组长度// 外层循环,遍历数组中的每个元素(除最后一个元素)for (int i = 0; i < n - 1; i++) {int minIndex = i; // 假设当前位置为最小值的索引// 内层循环,在未排序的部分中找到最小值的索引for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) { // 如果当前元素比最小值还小minIndex = j; // 更新最小值的索引}}// 将找到的最小值与当前位置的元素交换int temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}
}

算法时间复杂度分析:

情况时间复杂度计算公式
最好情况 O ( n 2 ) O(n^2) O(n2) T ( n ) = ∑ i = 1 n ( n − i + 1 ) = n ( n + 1 ) 2 = O ( n 2 ) T(n) = \sum_{i = 1}^{n}(n - i + 1) = \frac{n(n + 1)}{2} = O(n^2) T(n)=i=1n(ni+1)=2n(n+1)=O(n2)
平均情况 O ( n 2 ) O(n^2) O(n2) T ( n ) = ∑ i = 1 n ( n − i + 1 ) = n ( n + 1 ) 2 = O ( n 2 ) T(n) = \sum_{i = 1}^{n}(n - i + 1) = \frac{n(n + 1)}{2} = O(n^2) T(n)=i=1n(ni+1)=2n(n+1)=O(n2)
最坏情况 O ( n 2 ) O(n^2) O(n2) T ( n ) = ∑ i = 1 n ( n − i + 1 ) = n ( n + 1 ) 2 = O ( n 2 ) T(n) = \sum_{i = 1}^{n}(n - i + 1) = \frac{n(n + 1)}{2} = O(n^2) T(n)=i=1n(ni+1)=2n(n+1)=O(n2)

五、选择排序的特性

选择排序具有以下特性:

  1. 不稳定性:在选择排序中,相同元素的相对位置可能会发生变化,导致算法是不稳定的。例如,考虑数组 [ 5 , 2 , 5 , 1 ] [5, 2, 5, 1] [5,2,5,1],第一个 5 5 5 1 1 1 会交换位置,导致第一个 5 5 5 与第二个 5 5 5 的相对位置改变。
  2. 简单直观:选择排序是一种简单直观的排序算法,易于理解和实现。它的核心思想是每次从待排序的元素中选择最小(或最大)的元素,将其放到已排序序列的末尾。
  3. 时间复杂度:选择排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中 n n n 是数组的长度。这是因为它包含了两层嵌套的循环,每次内层循环都要遍历剩余未排序的部分来寻找最小值。
  4. 空间复杂度:选择排序的空间复杂度为 O ( 1 ) O(1) O(1),因为它只需要常数级别的额外空间来存储临时变量和进行元素交换。
  5. 适用性:尽管选择排序通常不是最有效的排序算法,但在某些特定情况下,它可能是一个不错的选择。例如,对小型数组或者已经基本有序的数组进行排序时,选择排序的性能可能比较好。
  6. 不需要额外的空间:选择排序是一种原地排序算法,不需要额外的空间来存储临时数据。这意味着它在空间上的开销比较小,适用于内存受限的环境。

推荐阅读

  1. Spring 三级缓存
  2. 深入了解 MyBatis 插件:定制化你的持久层框架
  3. Zookeeper 注册中心:单机部署
  4. 【JavaScript】探索 JavaScript 中的解构赋值
  5. 深入理解 JavaScript 中的 Promise、async 和 await

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

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

相关文章

Kafka初步学习

kafka消息队列模式 点对点模式&#xff1a;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除 消息生产者生产消息发送到queue中&#xff0c;然后消息消费者从queue中取出并且消费消息 消息被消费以后&#xff0c;queue中不再有存储&#xff0c;所以消息消费…

【DevOps】网站安全事件分析方法详解和实战分析

目录 一、网站安全事件分析流程 二、常用的网站安全事件分析方法 三、网站被植入挖矿脚本事件分析 1、 事件发现与确认 2、 事件隔离与取证 3、 事件分析与溯源 4、 事件处置与恢复 5、 事件总结与改进 四、网站安全事件分析的关键点 五、提高网站安全事件分析能力的…

python使用appium截图手机屏幕图片

要使用 Appium 截取手机屏幕图片并在电脑上显示&#xff0c;你需要执行几个步骤。以下是一个基本的流程&#xff1a; 设置 Appium 环境&#xff1a;确保你已经安装了 Appium 服务器和 Python 客户端库&#xff08;如 appium-python-client&#xff09;。编写 Python 脚本&…

详解大厂实时数仓建设V4.0

一、实时数仓建设背景 1. 实时需求日趋迫切 目前各大公司的产品需求和内部决策对于数据实时性的要求越来越迫切&#xff0c;需要实时数仓的能力来赋能。传统离线数仓的数据时效性是 T1&#xff0c;调度频率以天为单位&#xff0c;无法支撑实时场景的数据需求。即使能将调度频…

参数传递和剪枝,从修剪二叉树谈起

669. 修剪二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 一、参数传递 Java中的参数传递方式只有一种&#xff0c;那就是值传递。如果我们传的是基本数据类型&#xff0c;那么函数接收到的就是该数据的副本&#xff0c;如果我们传的是对象&#xff0c;那么函数接收到的就…

Uniapp与第三方应用数据通讯

首先说明一点&#xff0c;这个只是uniapp代码编写的应用之间相互传递数据&#xff0c;uniapp编写的与其他语言编写的我尚不知道能不能传递。 应用1&#xff1a; plus.runtime.launchApplication({pname: "应用的appid",// extra 中可以自定数据&#xff0c;url和da…

【Qt知识】部分QWidget属性表格

QWidget是Qt库中所有图形用户界面组件的基类&#xff0c;它提供了大量属性以供自定义和配置控件的行为和外观。下面列出了一些主要的QWidget属性及其作用。 属性 作用 accessibleName 控件的辅助技术名称&#xff0c;用于无障碍访问。 accessibleDescription 控件的辅助技…

详解MySQL的间隙锁

MySQL 的间隙锁&#xff08;Gap Lock&#xff09; 间隙锁&#xff08;Gap Lock&#xff09;是 InnoDB 存储引擎中的一种锁机制&#xff0c;用于防止幻读现象。幻读是指在一个事务中&#xff0c;两次读取同一个范围的数据时&#xff0c;第二次读取出现了第一次没有出现的数据行…

CSS真题合集(一)

CSS真题合集&#xff08;一&#xff09; 1. 盒子模型1.1 盒子模型的基本组成1.2 盒子模型的实际大小1.3 盒子模型的两种类型1.4 设置盒子模型1.5 弹性盒子模型 2. BFC2.1 主要用途2.2 触发BFC的方法2.2 解决外边距的塌陷问题&#xff08;垂直塌陷&#xff09; 3. 响应式布局3.1…

接口自动化框架封装思想建立(全)

httprunner框架&#xff08;上&#xff09; 一、什么是Httprunner&#xff1f; 1.httprunner是一个面向http协议的通用测试框架&#xff0c;以前比较流行的是2.X版本。 2.他的思想是只需要维护yaml/json文件就可以实现接口自动化测试&#xff0c;性能测试&#xff0c;线上监…

spring aop小记

一、aop概念 面向切面编程 参考&#xff1a;https://blog.csdn.net/lhj520cb/article/details/125820513 常用术语解释&#xff08;根据代码理解的&#xff09;&#xff1a; Aspect(切面)&#xff1a;Advice 通知(即增强)和 Pointcut 切点的结合。&#xff08;数学上可以理…

#define 和 const 定义常量的区别

文章目录 一、数组定义1.1 全局作用域中定义数组1.2 局部作用域定义数组 二、细节补充2.1 #define 和 const 的区别2.2 全局数组和局部数组的区别2.3 编译时常量 vs 运行时常量2.4 为什么局部作用域不要求编译时常量 总结 一、数组定义 1.1 全局作用域中定义数组 在全局作用域…

【Android面试八股文】Java异常机制中,异常Exception与错误Error区别是什么?

Java异常机制中,异常Exception与错误Error区别是什么? 这道题想考察什么? 在开发时需要时候需要自定义异常时,应该选择定义Excption还是Error? 编写的代码触发Excption或者Error分别代表什么? 考察的知识点 Java异常机制 考生应该如何回答 在Java中存在一个 Throwa…

Git - 详解 创建一个新仓库 / 推送现有文件夹 / 推送现有的 Git 仓库 到私有Gitlab

文章目录 【推送现有文件夹】详细步骤指令说明Git 全局设置设置Git全局用户名设置Git全局电子邮件地址 推送现有文件夹1. 进入现有文件夹2. 初始化Git仓库并设置初始分支为main3. 添加远程仓库4. 添加所有文件到暂存区5. 提交更改6. 推送代码到远程仓库并设置上游分支 创建一个…

ESXi内安装OpenWrt

目录 0、前言 1、环境 2、转换格式 3、创建虚拟机 4、OpenWrt设置 5、单臂流量测试 6、总结 0、前言 前几天在ESXi中先安装了PVE,然后在PVE中安装OpenWrt,没有来得及深入测试,仅仅作为安装和熟悉PVE的过程。后来转念一想为什么不在ES…

js之this

最近写代码学习了this&#xff0c;这个非常好用啊&#xff0c;今天拿出来给大家分享一下&#xff0c;根据我的理解以及前辈们的讲解 this 关键字代表当前执行上下文中的对象。它通常指向调用函数的对象&#xff0c;但其值可能取决于函数的调用方式。 全局上下文中的 this&…

项目经验,用什么思路去叙述?

文章目录 前言一、项目经验二、关于自学 前言 如果你的项目掌握的不高&#xff0c;面试官对项目的拷打&#xff0c;hold不住怎么办&#xff1f;首先一定要把项目说通透&#xff0c;一定要会说&#xff0c;就算可能没真实做过一个项目&#xff0c;会说出来讲通透就行。写在简历…

CS1061 “HtmlHelper”未包含“Partial”的定义,并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1061 “HtmlHelper”未包含“Partial”的定义&#xff0c;并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”(是否缺少 using 指令或程序集引用?) 14_Views_Message_E…

找嵌入式软件工作,freertos要掌握到什么程度?

对于嵌入式软件工程师来说&#xff0c;掌握RTOS&#xff08;实时操作系统&#xff09;的程度并不是决定性因素&#xff0c;而更重要的是工程思维和解决问题的能力。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习嵌入式…

GitHub个人访问令牌登录

生成个人访问令牌 登录 GitHub。访问 Personal Access Tokens 页面。点击 “Generate new token”。为令牌选择一个描述性名称。选择 repo 权限。点击 “Generate token” 生成令牌。复制生成的令牌。 推送命令 设置存储库 URL&#xff08;如果需要&#xff09;&#xff1a;…