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

排序(冒泡排序、选择排序、插入排序、希尔排序)-->深度剖析(一)

欢迎来到我的Blog,点击关注哦💕

前言

排序是一种基本的数据处理操作,它涉及将一系列项目重新排列,以便按照指定的标准(通常是数值大小)进行排序。在C语言中,排序算法是用来对元素进行排序的一系列步骤。

排序的概况

C语言中的排序算法是一系列用于将一组数据按照特定顺序进行排列的算法。这些算法通常根据元素之间的大小关系来确定它们在最终排序结果中的位置。

衡量排序的标准

  • 时间复杂度(参考:时间空间复杂度介绍)
  • 辅助空间:有些排序算法在排序过程中需要额外的空间来辅助排序,例如归并排序和快速排序。这些算法的辅助空间通常为O(n),而有些算法如插入排序和冒泡排序的辅助空间为O(1)
  • 稳定性:稳定性是指在排序过程中,相等键值的元素在原始序列中的相对位置是否保持不变。稳定排序算法会维持相等元素的相对次序,而不稳定排序算法则可能改变这些元素的相对次序。
  • 特殊情况下性能:某些排序算法在特定情况下可能表现得更优,例如当数据已经部分有序时,插入排序和冒泡排序可能会更快。而快速排序在这种情况下可能会变慢。

冒泡排序(Bubble Sort)

冒泡排序概念

冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。这个过程会重复进行,直到没有再需要交换的元素,这意味着数列已经排序完成。这个过程就像是气泡一样,较小(或较大)的元素会逐渐“冒泡”到列表的顶端

在这里插入图片描述

代码实现

冒泡排序算法的实现通常涉及两个嵌套的for循环。外层循环控制每一轮的比较次数,内层循环用于比较相邻元素并进行交换。

//冒泡排序
void BubbleSort(int* a, int n)
{for (int i = 0; i < n; i++){for (int j = i; j < n-i-1; j++){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);}}}
}

优化冒泡排序

当冒泡排序遇见 {2,1,4,5,6,7,8,9,10} 这样的数据就会大大折扣性能。如遇见如此的数据进行排序,我们可以定义一个bool类型flag = false 当数据进行交换的时候我们改变flag;

代码如下:

//冒泡排序
void BubbleSort(int* a, int n)
{for (int i = 0; i < n; i++){bool flag = false;for (int j = i; j < n-i-1; j++){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);flag = true;}if (flaf == false){break;}}}
}

冒泡排序复杂度分析

冒泡排序算法的时间复杂度为O(n^2), 这是因为在最坏的情况下,即数组完全逆序时,冒泡排序需要进行n-1轮比较和交换,其中n是数组的长度。每一轮比较需要比较n-i次(i为当前轮数),因此总的比较次数为n*(n-1)/2。所以,冒泡排序的时间复杂度为O(n^2)

选择排序(Selection Sort)

选择排序的概念

选择排序(Selection Sort)是一种简单直观的排序算法,它的基本思想是在每一轮中从不排序的子序列中选取最小(或最大)的元素,将其与子序列的起始位置的元素交换,从而逐渐构建起有序序列。

在这里插入图片描述

代码实现

选择排序思想简单,排序大->小(小->大),就遍历数组记录即可。

//交换
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}//选择排序
void SelectSort(int* a, int n)
{int min = 0;int begin = 0;while (begin < n - 1){for (int i = begin; i < n; i++){if (a[i] < a[min]){min = i;}}Swap(&a[min], &a[begin]);++begin;}
}

优化选择排序

选择排序可以通过一些优化手段进行提升,例如使用哨兵变量来减少内层循环的判断次数等。这些优化手段可以在一定程度上提高选择排序的执行效率。(在这里就不实现了

选择排序的复杂度分析

选择排序的时间复杂度为 O(n^2),其中n是数组的长度。这是因为算法需要进行两层循环,外层循环控制排序的轮数,内层循环则负责在每一轮中找到最小元素。

插入排序(Insertion Sort)

插入排序的概念

插入排序是一种简单直观的排序算法,它的基本思想是将未排序的元素插入到已排序元素形成的有序序列中。在每一轮排序中,都会将一个待排序的元素插入到它应该所在的位置,直到所有元素都被插入完毕。
在这里插入图片描述

代码实现

定义循环进行比较将大(小)的值相后面依次挪动,直至寻找到比自己小(大)的值位置进行插入。

//插入排序
void InsertionSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}

插入排序的优化

  • 可以进行二分插入,它通过二分查找来确定待插入位置,从而减少了比较和移动的次数。
  • 希尔排序是对直接插入排序的优化,它通过增加一个间隙因子来分组排序,使得每个组内部的元素可以先进行排序,然后逐渐减小间隙因子,直到间隙因子为1,此时整个数组已经接近有序,插入排序的效率会得到提高

插入排序复杂度分析

  • 最佳情况:如果输入数组已经是完全有序的,插入排序只需要进行 n 次比较(每次比较后插入一个元素到已排序部分),而不需要进行任何交换。在这种情况下,时间复杂度是 O(n)
  • 平均情况:在平均情况下,插入排序的时间复杂度是 O(n^2)。这是因为每个元素都需要与已排序部分的多个元素进行比较,平均下来,每个元素需要比较 n/2 次。
  • 最坏情况:如果输入数组是完全逆序的,插入排序需要进行 n(n-1)/2 次比较和 n(n-1)/2 次交换,时间复杂度是 O(n^2)

希尔排序(Shell Sort)

希尔排序的概念

希尔排序(Shell Sort)是一种基于插入排序的算法,它通过引入增量序列,采取分组排序策略:将大数组分为若干个子序列,对每个子序列进行插入排序。随着增量逐渐减小,子序列变得更小,最终达到增量为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 (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

希尔排序复杂度分析

希尔排序算法的平均时间复杂度通常被认为是介于 O(n log n) 和 O(n^2) 之间,具体取决于所选择的间隔序列。在最佳情况下,当间隔序列满足特定条件时,希尔排序可以达到接近 O(n) 的时间复杂度。然而,在最坏情况下,希尔排序的时间复杂度为 O(n^2)。

break;}}a[end + gap] = tmp;}
}

}


## 希尔排序复杂度分析希尔排序算法的平均时间复杂度通常被认为是介于 O(n log n) 和 O(n^2) 之间,具体取决于所选择的间隔序列。在最佳情况下,当间隔序列满足特定条件时,希尔排序可以达到接近 O(n) 的时间复杂度。然而,在最坏情况下,希尔排序的时间复杂度为 O(n^2)。

相关文章:

排序(冒泡排序、选择排序、插入排序、希尔排序)-->深度剖析(一)

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言 排序是一种基本的数据处理操作&#xff0c;它涉及将一系列项目重新排列&#xff0c;以便按照指定的标准&#xff08;通常是数值大小&#xff09;进行排序。在C语言中&#xff0c;排序算法是用来对元素进行排序的一系…...

(2024)docker-compose实战 (6)部署前端项目(react, vue)

前言 本次仅使用nginx搭建单一的前端项目, 前端项目可以是html, react, vue.项目目录中需要携带nginx的配置文件(conf/default.conf).前端文件直接拷贝到项目目录中即可.如果不确定镜像的配置文件目录, 可以通过 docker inspect 镜像名 来查看具体的配置信息.使用docker-compos…...

python 中的 下划线_ 是啥意思

在 Python 中&#xff0c;_&#xff08;下划线&#xff09;通常用作占位符&#xff0c;表示一个变量名&#xff0c;但程序中不会实际使用这个变量的值。 目录 忽略循环变量&#xff1a;忽略函数返回值&#xff1a;在解释器中使用&#xff1a;举例子1. 忽略循环变量2. 忽略不需…...

Solana公链

Solana是一个高性能的区块链平台&#xff0c;其设计目标是在不牺牲去中心化或安全性的情况下提供可扩展性。Solana由前高通、英特尔及Dropbox的工程师于2017年末创立。以下是Solana的一些关键特点&#xff1a; 高吞吐量&#xff1a;Solana能够每秒处理高达65,000笔交易&#xf…...

【LeetCode】反转字符串中的单词

目录 一、题目二、解法完整代码 一、题目 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1…...

[leetcode]文件组合

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<vector<int>> fileCombination(int target) {vector<vector<int>> vec;vector<int> res;int sum 0, limit (target - 1) / 2; // (target - 1) / 2 等效于 target /…...

数据库断言

预期值和实际值做对比 步骤&#xff1a; 1、得到表格数据 2、接口断言预期值与实际值做对比 读取表格数据-得到接口地址&#xff08;address)和是否接口db检查(dbcheck)&#xff0c;并且这条数据是有效的(vaild) 有2条用例&#xff0c;也会有三个条件不全部满足的情况&…...

uniapp+nodejs实现小程序支付

1.准备商户号、企业级小程序(或者个体工商户级别的) 2.在小程序端调用uni.login获取code&#xff0c;传递给后端 uni.login({success: loginRes > {uni.request({url: "http://127.0.0.1:3003/wxpay/pay",data: {code: loginRes.code},method: "get",…...

SolidityFoundry 安全审计测试 memory滥用

名称&#xff1a; memory滥用 https://github.com/XuHugo/solidityproject/tree/master/vulnerable-defi 描述&#xff1a; 在合约函数中滥用storage和memory。 memory是一个关键字&#xff0c;用于临时存储执行合约所需的数据。它保存函数的参数数据&#xff0c;并在执行后…...

面试题--SpringBoot

SpringBoot SpringBoot 是什么(了解) 是 Spring 的子项目,主要简化 Spring 开发难度,去掉了繁重配置,提供各种启动器,可以 让程序员很快上手,节省开发时间. SpringBoot 的优点(必会) SpringBoot 对上述 Spring 的缺点进行的改善和优化&#xff0c;基于约定优于配置的思想&am…...

Stable Diffusion中放大图像的3种方法

前言 要执行 ControlNet tile upscale&#xff1a; 您想使用 Stable Diffusion 创建包含大量细节的大型图像吗&#xff1f;您将需要使用升频器。在本文中&#xff0c;您将学习 3 种放大图像的方法。 人工智能升级器标清高档ControlNet瓷砖高档 您将看到比较并了解这些方法的优…...

生产者消费模式

前言&#x1f440;~ 上一章我们介绍设计模式中的单例模式&#xff0c;今天我们来讲讲生产者消费模式 阻塞队列&#xff08;重要&#xff09; 生产者消费模式&#xff08;重要&#xff09; 阻塞队列在生产者消费模型中的作用 标准库的阻塞队列 手动实现阻塞队列 如果各位对…...

PyMuPDF 操作手册 - 06 PDF的转换等

文章目录 七、转换 PDF 文档7.1 将pdf文本提取为 Markdown7.2 将pdf转换为word(使用`pdf2docx`库)7.2.1 安装pdf2docx7.2.2 转换所有页面7.2.3 转换指定页面7.2.4 多CPU核心处理7.2.5 转换加密的 pdf7.2.6 提取表格7.2.7 pdf2docx 和 python_docx 的关系7.3 PDF与图像的转换七…...

VUE3解决跨域问题

本文基于vue3 vite element-plus pnpm 报错&#xff1a;**** has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource. 原因&#xff1a;前端不能直接访问其他IP&#xff0c;需要用vite.config.ts &#xff0…...

2024阿里云大模型自定义插件(如何调用自定义接口)

1&#xff0c;自定义插件入口 2&#xff0c;插件定义&#xff1a;描述插件的参数 2.1&#xff0c;注意事项&#xff1a; 2.1.1&#xff0c;只支持json格式的参数&#xff1b;只支持application/JSON&#xff1b;如下图&#xff1a; 2.1.2&#xff0c;需要把接口描述进行修改&a…...

生成式人工智能将如何改变网络可访问性

作者&#xff1a;Matthew Adams 受 Be My Eyes 和 OpenAI 启发的一项实验&#xff0c;尝试使用 ChatGPT 4o 实现网页无障碍 在 Elastic&#xff0c;我们肩负着一项使命&#xff0c;不仅要构建最佳的搜索驱动型 AI 平台&#xff0c;还要确保尽可能多的人喜欢使用该平台。我们相…...

科普文:一文搞懂jvm实战(二)Cleaner回收jvm资源

概叙 在JDK9中新增了Cleaner类&#xff0c;该类的作用是用于替代finalize方法&#xff0c;更有效地释放资源并避免内存泄漏。 在JEP260提案中&#xff0c;封装了大部分Sun包内部的API之余&#xff0c;还引入了一些新的API&#xff0c;其中就包含着Cleaner这个工具类。Cleaner承…...

使用PyTorch高效读取二进制数据集进行训练

使用pickle制作类cifar10二进制格式的数据集 使用pytorc框架来训练&#xff08;以猫狗大战数据集为例&#xff09; 此方法是为了实现阿里云PAI studio上可视化训练模型时使用的数据格式。 一、制作类cifar10二进制格式数据 import os, cv2 from pickled import * from load_da…...

应急响应:应急响应流程,常见应急事件及处置思路

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这一章节我们需…...

Kotlin/Android中执行HTTP请求

如何在Kotlin/Android中执行简单的HTTP请求 okhttp官网 okhttp3 github地址 打开build.gradle.kts文件加入依赖 dependencies {implementation("com.squareup.okhttp3:okhttp:4.9.0") }在IDEA的Gradle面板点击reload按钮便会自动下载jar...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...