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

排序算法之基础排序:冒泡,选择,插入排序详解

排序算法之基础排序:冒泡、选择、插入排序详解

  • 前言
  • 一、冒泡排序(Bubble Sort)
    • 1.1 算法原理
    • 1.2 代码实现(Python)
    • 1.3 性能分析
  • 二、选择排序(Selection Sort)
    • 2.1 算法原理
    • 2.2 代码实现(Java)
    • 2.3 性能分析
  • 三、插入排序(Insertion Sort)
    • 3.1 算法原理
    • 3.2 代码实现(C++)
    • 3.3 性能分析
  • 四、三种基础排序算法的对比与应用场景
    • 算法对比
    • 应用场景
  • 总结

前言

排序算法是数据处理的基础且重要的组成部分,冒泡排序、选择排序和插入排序作为基础排序算法,虽然在效率上不及一些高级排序算法,但它们原理简单、易于理解,是学习排序算法的入门之选,也是理解更复杂排序算法的基础。本文我将详细介绍这三种基础排序算法的原理、实现代码、性能分析以及实际应用场景。

一、冒泡排序(Bubble Sort)

1.1 算法原理

冒泡排序的基本思想是重复地走访过要排序的数列,一次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个过程就像水中的气泡,较小(或较大)的元素会逐渐 “浮” 到数列的顶端,因此得名冒泡排序。

具体过程如下:

比较相邻的元素。如果第一个比第二个大(升序排序),就交换它们两个。

对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
冒泡

1.2 代码实现(Python)

def bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n - i - 1):if arr[j] > arr[j + 1]:arr[j], arr[j + 1] = arr[j + 1], arr[j]return arr

在上述代码中,外层循环控制排序的轮数,一共需要n轮(n为数组长度)。内层循环用于每一轮中相邻元素的比较和交换,随着外层循环的进行,每一轮比较的次数逐渐减少,因为每一轮结束后,最大的元素已经 “沉” 到了数组末尾。

1.3 性能分析

时间复杂度

最好情况:当数组已经是有序状态时,冒泡排序只需要进行一次遍历,比较n - 1次,不需要交换元素,时间复杂度为 O ( n ) O(n) O(n)

最坏情况:当数组是逆序状态时,需要进行 n ( n − 1 ) / 2 n(n - 1) / 2 n(n1)/2次比较和交换操作,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

平均情况:时间复杂度同样为 O ( n 2 ) O(n^2) O(n2)

空间复杂度:冒泡排序只需要使用常数级别的额外空间来进行元素交换,空间复杂度为 O ( 1 ) O(1) O(1)

稳定性:冒泡排序是一种稳定的排序算法,因为在比较和交换元素时,相同元素的相对顺序不会改变。

二、选择排序(Selection Sort)

2.1 算法原理

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

具体步骤如下:

在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。
选择排序

2.2 代码实现(Java)

public class SelectionSort {public static int[] 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;}return arr;}public static void main(String[] args) {int[] arr = {64, 25, 12, 22, 11};int[] sortedArr = selectionSort(arr);for (int num : sortedArr) {System.out.print(num + " ");}}
}

上述 Java 代码中,外层循环控制排序的轮数,一共需要n - 1轮(n为数组长度)。内层循环用于在每一轮中找到未排序部分的最小元素的索引,然后将其与当前轮起始位置的元素交换。

2.3 性能分析

时间复杂度

最好情况:即使数组已经是有序的,选择排序也需要进行 n ( n − 1 ) / 2 n(n - 1) / 2 n(n1)/2次比较,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

最坏情况:同样需要进行 n ( n − 1 ) / 2 n(n - 1) / 2 n(n1)/2次比较和交换操作,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

平均情况:时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度:选择排序只需要使用常数级别的额外空间来进行元素交换,空间复杂度为 O ( 1 ) O(1) O(1)

稳定性:选择排序是不稳定的排序算法,因为在选择最小元素并交换位置时,可能会改变相同元素的相对顺序。例如,数组[5, 5, 3],在排序过程中两个5的相对顺序可能会发生变化。

三、插入排序(Insertion Sort)

3.1 算法原理

插入排序的基本思想是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。其操作过程就像玩扑克牌时整理手中牌的过程,每次从 “牌堆” 中摸一张牌,插入到手中已整理好的牌的合适位置。

具体过程如下:

从第一个元素开始,该元素可以认为已经被排序。

取出下一个元素,在已经排序的元素序列中从后向前扫描。

如果该元素(已排序)大于新元素,将该元素移到下一位置。

重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置。

将新元素插入到该位置后。

重复步骤 2~5,直到所有元素均排序完毕。
插入排序

3.2 代码实现(C++)

#include <iostream>
#include <vector>
using namespace std;vector<int> insertionSort(vector<int> arr) {int n = arr.size();for (int i = 1; i < n; ++i) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}return arr;
}

在 C++ 代码中,外层循环从数组的第二个元素开始(因为第一个元素默认已排序)。内层循环用于在已排序部分中找到合适的插入位置,将当前元素插入到正确的位置,使得已排序部分始终保持有序。

3.3 性能分析

时间复杂度

最好情况:当数组已经是有序状态时,每插入一个元素只需要比较一次,不需要移动元素,时间复杂度为 O ( n ) O(n) O(n)

最坏情况:当数组是逆序状态时,插入每个元素都需要比较和移动i次(i为当前元素的索引),时间复杂度为 O ( n 2 ) O(n^2) O(n2)

平均情况:时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度:插入排序只需要使用常数级别的额外空间来保存当前要插入的元素,空间复杂度为 O ( 1 ) O(1) O(1)

稳定性:插入排序是稳定的排序算法,因为在插入元素时,相同元素的相对顺序不会改变。

四、三种基础排序算法的对比与应用场景

算法对比

排序算法时间复杂度(最好)时间复杂度(最坏)时间复杂度(平均)空间复杂度稳定性
冒泡排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
选择排序 O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)不稳定
插入排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定

应用场景

冒泡排序:由于其简单易懂,常用于教学场景帮助初学者理解排序算法的基本概念。在数据规模较小且对时间要求不高的情况下,也可以使用。

选择排序:适用于对稳定性要求不高,且数据规模较小的排序场景。比如在一些简单的游戏内数据排序或者资源管理系统中,当数据量不大时可以使用。

插入排序:对于部分有序的数组或者数据量较小的数组,插入排序表现较好。例如,在数据库的某些索引维护操作中,如果数据更新后仍保持部分有序,插入排序可以高效地对新数据进行插入和排序。

总结

冒泡排序、选择排序和插入排序作为基础排序算法,虽然在时间复杂度上都为 O ( n 2 ) O(n^2) O(n2),在处理大规模数据时效率较低,但它们的原理简单,实现容易,是学习排序算法的重要基石。通过理解这三种算法,我们可以更好地掌握排序算法的基本思想,为学习更复杂高效的排序算法(快速排序、归并排序、堆排序等)打下坚实的基础。在下期博客中,我将深入探讨快速排序与归并排序这两种高效排序算法,详细解析它们的实现机制、性能特点以及在不同场景下的应用优势,帮助大家进一步拓宽对排序算法的认知边界。

That’s all, thanks for reading!
创作不易,点赞鼓励;
知识无价,收藏备用;
持续精彩,关注不错过!

相关文章:

排序算法之基础排序:冒泡,选择,插入排序详解

排序算法之基础排序&#xff1a;冒泡、选择、插入排序详解 前言一、冒泡排序&#xff08;Bubble Sort&#xff09;1.1 算法原理1.2 代码实现&#xff08;Python&#xff09;1.3 性能分析 二、选择排序&#xff08;Selection Sort&#xff09;2.1 算法原理2.2 代码实现&#xff…...

Linux常用命令42——tar压缩和解压缩文件

在使用Linux或macOS日常开发中&#xff0c;熟悉一些基本的命令有助于提高工作效率&#xff0c;tar 是 Linux 和 Unix 系统中用于归档文件和目录的强大命令行工具。tar 名字来自 "tape archive"&#xff08;磁带归档&#xff09;&#xff0c;最初用于将文件打包到磁带…...

网络协议分析 实验七 FTP、HTTP、DHCP

文章目录 实验7.1 FTP协议练习二 使用浏览器登入FTP练习三 在窗口模式下&#xff0c;上传/下传数据文件实验7.2 HTTP(Hyper Text Transfer Protocol)练习二 页面提交练习三 访问比较复杂的主页实验7.3 DHCP(Dynamic Host Configuration Protocol) 实验7.1 FTP协议 dir LIST&…...

HTML 表格与div深度解析区别及常见误区

一、HTML<div>元素详解 <div>是HTML中最基本的块级容器元素&#xff0c;本身没有语义&#xff0c;主要用于组织和布局页面内容。以下是其核心用法&#xff1a; 1. 基础结构与特性 <div><!-内部可包含任意HTML元素 --><h2>标题</h2><p…...

Linux 系统中设置开机启动脚本

Linux 系统中设置开机启动脚本有多种方法,适用于不同的场景和需求。以下是几种最常用且详细的方法: 核心理念: 无论哪种方法,核心都是让系统在启动过程中的某个阶段执行你的脚本。 1. 使用 systemd (推荐,现代 Linux 发行版的标准) systemd 是目前大多数主流 Linux 发行…...

linux-进程信号的产生

Linux中的进程信号&#xff08;signal&#xff09;是一种用于进程间通信或向进程传递异步事件通知的机制。信号是一种软中断&#xff0c;用于通知进程某个事件的发生&#xff0c;如错误、终止请求、计时器到期等。 1. 信号的基本概念 - 信号&#xff08;Signal&#xff09;&am…...

内容中台重构企业知识管理路径

智能元数据驱动知识治理 现代企业知识管理的核心挑战在于海量非结构化数据的有效治理。通过智能元数据分类引擎&#xff0c;系统可自动识别文档属性并生成多维标签体系&#xff0c;例如将技术手册按产品版本、功能模块、适用场景进行动态标注。这种动态元数据框架不仅支持跨部…...

ubuntu22.04卸载vscode

方法 1&#xff1a;通过 Snap 卸载 VSCode 如果你是通过 Snap 安装的 VSCode&#xff08;Ubuntu 22.04 默认推荐方式&#xff09;&#xff0c;按照以下步骤卸载&#xff1a; 检查是否通过 Snap 安装&#xff1a; bash snap list | grep code如果输出显示 code&#xff0c;说明…...

AGI大模型(19):下载模型到本地之ModelScope(魔搭社区)

1 安装模块 魔塔社区提供了下载的模块&#xff0c;如下&#xff1a; pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple 2 模型下载 from modelscope import snapshot_download model_dirsnapshot_download(LLM-Research/Meta-Llama-3-8B,cache_dirrD:\…...

基于Spring Boot+Layui构建企业级电子招投标系统实战指南

一、引言&#xff1a;重塑招投标管理新范式 在数字经济浪潮下&#xff0c;传统招投标模式面临效率低、透明度不足、流程冗长等痛点。本文将以Spring Boot技术生态为核心&#xff0c;融合Mybatis持久层框架、Redis高性能缓存及Layui前端解决方案&#xff0c;构建一个覆盖招标代理…...

Kali安装详细图文安装教程(文章内附有镜像文件连接提供下载)

Kali镜像文件百度网盘&#xff1a;通过网盘分享的文件&#xff1a;kali-linux-2024.2-installer-amd64.iso 链接: https://pan.baidu.com/s/1MfCXi9KrFDqfyYPqK5nbKQ?pwdSTOP 提取码: STOP --来自百度网盘超级会员v5的分享 1.下载好镜像文件后&#xff0c;我们打开我们的VMwa…...

2.4GHz无线芯片核心技术解析与典型应用

2.4G芯片作为工作在2.4GHz ISM频段的无线通信集成电路&#xff0c;主要面向短距离数据传输应用。这类芯片具有以下技术特点&#xff1a; 多协议支持 兼容蓝牙、Wi-Fi和ZigBee等主流协议 采用SDR技术实现协议灵活切换 适用于智能家居和物联网设备 低功耗特性 采用休眠唤醒和动态…...

ai agent(智能体)开发 python高级应用4:什么是代理,如何设置squid代理服务器,让crawl4ai 0.6.3 用上代理,获取到数据平权

crawl4ai 0.6.3为啥用代理&#xff0c;什么情况下需要用到代理 在 crawl4ai 中设置代理服务器的好处&#xff1a; 一、设置代理的好处 避免IP封禁 高频请求同一网站时&#xff0c;目标服务器可能封禁真实IP。代理通过轮换IP分散请求&#xff0c;降低封禁风险。 绕过地理限制 …...

技术融资:概念与形式、步骤与案例、挑战与应对、发展趋势

一、技术融资概述 技术融资是指通过外部资金支持技术研发、产品开发或市场扩展的过程。它通常涉及风险投资、天使投资、私募股权、众筹等多种形式。技术融资的核心目标是为技术创新提供资金保障&#xff0c;推动技术从概念到市场的转化。 技术融资的主要形式包括以下几种&…...

Chrome代理IP配置教程常见方式附问题解答

在网络隐私保护和跨境业务场景中&#xff0c;为浏览器配置代理IP已成为刚需。无论是访问地域限制内容、保障数据安全&#xff0c;还是管理多账号业务&#xff0c;掌握Chrome代理配置技巧都至关重要。本文详解三种主流代理设置方式&#xff0c;助你快速实现精准流量管控。 方式一…...

微信小程序 密码框改为text后不可见,需要点击一下

这个问题是做项目的时候碰到的。 密码框常规写法&#xff1a; <view class"inputBox"><view class"input-container"><input type"{{inputType}}" placeholder"请输入密码" data-id"passwordValue" bindin…...

LLM笔记(六)线性代数

公式速查表 1. 向量与矩阵&#xff1a;表示、转换与知识存储的基础 向量表示 (Vectors): 语义的载体 在LLM中&#xff0c;向量 x ∈ R d \mathbf{x}\in\mathbb{R}^d x∈Rd 是信息的基本单元&#xff0c;承载着丰富的语义信息&#xff1a; 词嵌入向量 (Word Embeddings)&am…...

Linux——UDP/TCP协议理论

1. UDP协议 1.1 UDP协议格式 系统内的UDP协议结构体&#xff1a; 注1&#xff1a;UDP协议的报头大小是确定的&#xff0c;为8字节 注2&#xff1a;可以通过报头中&#xff0c;UDP长度将UDP协议的报头和有效载荷分离&#xff0c;有效载荷将存储到接收缓冲区中等待上层解析。 注…...

Go语言爬虫系列教程(一) 爬虫基础入门

Go爬虫基础入门 1. 网络爬虫概念介绍 1.1 什么是网络爬虫 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称网页蜘蛛、网络机器人&#xff0c;是一种按照一定规则自动抓取互联网信息的程序或脚本。其核心功能是模拟人类浏览网页的行为&#xff0c;通过发送网络…...

PromptIDE提示词开发工具支持定向优化啦

老粉们都知道&#xff0c;PromptIDE 是一款专门解决 AI 提示词生成和优化的工具&#xff0c;让 AI 真正听懂你在说什么&#xff0c;生成更符合预期的结果&#xff01; 我们这次更新主要争对提示词优化这一块&#xff0c;推出了不同提示词优化方向&#xff0c;贴近用户需求。 举…...

多返回值(Multiple Return Values)- 《Go语言实战指南》

Go 语言支持函数返回多个值&#xff0c;这一特性在实际开发中非常常见&#xff0c;尤其用于错误处理。 一、函数返回多个值的基本语法 func 函数名(参数列表) (返回值1类型, 返回值2类型, ...) {// 函数体return 值1, 值2, ... } 示例&#xff1a;计算商和余数 func divide(…...

致远OA人事标准模块功能简介【附应用包百度网盘下载地址,官方售价4W】

人事管理应用&#xff0c;围绕岗位配置、招聘管理、员工档案、入转调离、员工自助申报、数据信息管理等人力资源管理关键业务&#xff0c;构建全员可参与的人事工作协同平台&#xff0c;让人事从繁杂琐碎的事务中解脱出来&#xff0c;高质高效工作&#xff0c;让管理层清楚掌握…...

Python-简单网络编程 I

目录 一、UDP 网络程序1. 通信结构图2. Python 代码实现1&#xff09;服务器端2&#xff09;客户端 3. 注意 二、TCP 网络程序1. 通信结构图2. Python 代码实现1&#xff09;服务器端2&#xff09;客户端 3. 注意 三、文件下载1. PyCharm 程序传参1&#xff09;图形化界面传参2…...

鸿蒙北向应用开发: deveco5.0 创建开源鸿蒙项目

本地已经安装deveco5.0 使用5.0创建开源鸿蒙项目 文件->新建->新建项目 直接创建空项目,一路默认 next 直接编译项目 直接连接开源鸿蒙5.0开发板编译会提示 compatibleSdkVersion and releaseType of the app do not match the apiVersion and releaseType on the dev…...

数据库故障排查指南:从入门到精通

1. 常见数据库故障类型 1.1 连接故障 数据库连接超时连接池耗尽网络连接中断认证失败1.2 性能故障 查询执行缓慢内存使用过高CPU使用率异常磁盘I/O瓶颈1.3 数据故障 数据不一致数据丢失数据损坏事务失败2. 故障排查流程 2.1 初步诊断 -- 检查数据库状态SHOW STATUS;SHOW PRO…...

国产linux系统(银河麒麟,统信uos)使用 PageOffice自定义Word模版中的数据区域

​ PageOffice 国产版 &#xff1a;支持信创系统&#xff0c;支持银河麒麟V10和统信UOS&#xff0c;支持X86&#xff08;intel、兆芯、海光等&#xff09;、ARM&#xff08;飞腾、鲲鹏、麒麟等&#xff09;、龙芯&#xff08;Mips、LoogArch&#xff09;芯片架构。 在实际的Wor…...

基于基金净值百分位的交易策略

策略来源&#xff1a;睿思量化小程序 基金净值百分位&#xff0c;是衡量当前基金净值在过去一段时间内的相对位置。以近一年为例&#xff0c;若某基金净值百分位为30%&#xff0c;意味着过去一年中有30%的时间基金净值低于当前值&#xff0c;70%的时间高于当前值。这一指标犹如…...

2025蓝桥杯JAVA编程题练习Day8

1. 路径 题目描述 小蓝学习了最短路径之后特别高兴&#xff0c;他定义了一个特别的图&#xff0c;希望找到图 中的最短路径。 小蓝的图由 2021 个结点组成&#xff0c;依次编号 1 至 2021。 对于两个不同的结点 a, b&#xff0c;如果 a 和 b 的差的绝对值大于 21&#xff0…...

通信安全堡垒:profinet转ethernet ip主网关提升冶炼安全与连接

作为钢铁冶炼生产线的安全检查员&#xff0c;我在此提交关于使用profinet转ethernetip网关前后对生产线连接及安全影响的检查报告。 使用profinet转ethernetip网关前的情况&#xff1a; 在未使用profinet转ethernetip网关之前&#xff0c;我们的EtherNet/IP测温仪和流量计与PR…...

DL00219-基于深度学习的水稻病害检测系统含源码

&#x1f33e; 基于深度学习的水稻病害检测系统 — 智能农业的未来&#xff0c;守护农田的每一寸土地&#xff01; &#x1f69c; 完整系统获取见文末 水稻病害检测&#xff0c;一直是农业领域的一大难题。传统的人工检测不仅耗时耗力&#xff0c;还容易因经验不足导致漏检或误…...