希尔排序-C语言版本

前言

从希尔开始,排序的速度就开始上升了,这里的排序开始上一个难度了,当然难一点的排序其实也不是很难,当你对于插入排序了解的足够深入的时候,你会发现其实希尔就是插入的异形,但是本质上还是一样的

希尔排序gif

希尔排序单趟实现

1,希尔排序本质就是插入排序的进化,插入排序是寻找比较进行插入,希尔这个人觉得插入排序有点慢,就觉得我们可不可以进行预排序,也就是数值原来是0-9的情况下,最坏的情况我们需要循环9次数才能找到需要插入的点在哪,那么此时我们能不能进行一个预排序

2,所谓的预排序就是,我们假设几个为一组,几个为一组,这个组的变量我们设置为gap。假设处置3个为一组,那么gap=3

3,此时我们可以把这一组,先采取插入排序的方式进行预排序,预排序之后我们就会发现这一组的这条线上的数值已经有序

4,多趟实现只是反复的实现第一趟的实现的逻辑

希尔排序的多趟实现

1,多趟实现只是反复的实现第一趟的实现的逻辑

2,我们需要先知道单趟遍历的时候,我们需要假设gap一组的,这个中间的元素是没有的,那么此时此时一组就是两个数值,我们需要让这两个数值进行交换

3,这两个数值交换之后我们这个时候需要循环开始插入排序的逻辑,也就是假设前面的两个数值是已经有序的,那么新插入的一个数值是需要排序的,我们进行排序

4,一趟结束之后,我们继续多趟实现,这几个数值继续预排序

5,继续预排序

6,此时gap=3,那么我们继续,gap/2=1,之后继续进行预排序,此时我们就得到了这个排序正确的数值

希尔排序代码的实现-版本1

//希尔排序
void ShellSort(int* a, int n)
{int gap = n - 1;//定义gap,这里循环停止的条件是>1,原因是+1了,已经恒大于0了,所以需要大于1,等于都不可以while (gap > 1){gap = gap / 3 + 1;//循环实现每一组for (int j = 0; j < gap; j++){//gap单趟实现for (int i = j; i < n - gap; i += gap){int end = i; int tmp = a[end + gap];//一组的实现while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}//交换找到的数值a[end + gap] = tmp;}}}
}

 解释:

  1. 函数ShellSort接受两个参数:一个指向整数数组a的指针和数组的长度n

  2. 初始化间隔gap为数组长度n - 1,这是希尔排序开始时的最大间隔。

  3. while循环用于逐步减小间隔,直到间隔为1。当gap大于1时,循环继续。

  4. 在每次while循环的开始,重新计算间隔gap。这里使用的是gap = gap / 3 + 1,这是一种常见的间隔序列,由Donald Shell提出。

  5. 外层for循环用于遍历数组,步长为当前的间隔gap

  6. 内层for循环用于实现插入排序,但仅限于间隔gap内的范围。

  7. 在内层循环中,end变量记录当前考虑的元素的索引,tmp变量暂存当前要插入的元素。

  8. while循环用于在间隔gap内从后向前扫描,找到tmp应该插入的位置。

  9. 如果tmp小于当前比较的元素a[end],则将a[end]向后移动一个间隔gap的距离,为tmp腾出空间。

  10. 如果tmp大于或等于a[end],则while循环结束,找到了tmp应该插入的位置。

  11. 循环结束后,将tmp赋值给a[end + gap],完成插入操作。

  12. 这个过程重复进行,直到数组中的所有元素都被扫描并插入到正确的位置。

代码逻辑:

  • 希尔排序通过多个插入排序的变体来工作,每个变体都有一个特定的间隔。
  • 初始时,间隔较大,排序的稳定性较差,但可以快速减少无序度。
  • 随着间隔逐渐减小,排序的稳定性逐渐提高,最终当间隔为1时,算法变为普通的插入排序,确保数组完全有序。

注意:

  • 希尔排序不是稳定的排序算法,因为它可能会改变相等元素的相对顺序。
  • 希尔排序的时间复杂度通常在 𝑂(𝑛log⁡𝑛) 和 𝑂(𝑛^2) 之间,具体取决于间隔序列的选择。
  • 希尔排序的空间复杂度是 𝑂(1,因为它是原地排序算法,不需要额外的存储空间。

希尔排序代码的实现-版本2

上面那个代码一般是教学使用,书写会更加详细理解,但是很多书本会这样写

这里的关键在于,不再进行先一组排序结束,再反过来进行下一组反复执行

而是直接这一组实现完毕之后,++,直接进行下一组的实现,本质上还是一样的

只是直接这样书写,容易不理解

//希尔排序
void ShellSort02(int* a, int n)
{int gap = n - 1;//定义gap,这里循环停止的条件是>1,原因是+1了,已经恒大于0了,所以需要大于1,等于都不可以while (gap > 1){gap = gap / 3 + 1;//循环实现每一组+//gap单趟实现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;}else{break;}}//交换找到的数值a[end + gap] = tmp;}}
}

解释:

  1. 函数ShellSort02接受两个参数:一个指向整数数组a的指针和数组的长度n

  2. 初始化间隔gap为数组的最后一个索引n - 1

  3. while循环用于逐步减小间隔,直到间隔小于或等于1。循环的条件是gap > 1,这是因为间隔在每次迭代中都会减小,所以不需要检查gap == 1的情况。

  4. while循环内部,重新计算间隔gap。这里使用的计算方法是gap = gap / 3 + 1,这是一种常见的间隔序列,旨在逐步减小间隔,直到达到1。

  5. 外层for循环遍历数组,直到i < n - gap,即遍历到数组的末尾减去当前间隔的位置。

  6. 在外层for循环中,end变量记录当前考虑的元素的索引,tmp变量暂存当前间隔位置的元素值。

  7. 内层while循环用于在数组中找到tmp应该插入的位置。它从当前索引end开始,向前以间隔gap的距离进行比较。

  8. 如果tmp小于当前比较的元素a[end],则将a[end]向后移动一个间隔gap的距离,为tmp腾出空间。

  9. 如果tmp大于或等于a[end],则while循环结束,找到了tmp应该插入的位置。

  10. 循环结束后,将tmp赋值给a[end + gap],完成插入操作。

  11. 这个过程重复进行,直到数组中的所有元素都被扫描并插入到正确的位置。

代码逻辑:

  • 希尔排序通过多个插入排序的变体来工作,每个变体都有一个特定的间隔。
  • 初始时,间隔较大,随着算法的进行,间隔逐渐减小,直到变为1,此时算法变为普通的插入排序。
  • 通过逐步减小间隔,希尔排序能够在每次迭代中对数组的更大范围内的元素进行排序,从而减少比较和移动的次数。

希尔排序gap的界定

一般来说,一组为多少这个不好说,希尔开始书写的时候,gap是/2,来进行书写的,但是被认为效率最高的是,除以3+1,但是/3+1有一个弊端就是这个是恒大于0的,所以终止条件应该换为大于1就继续循环,小于等于1就停止循环

希尔排序的时间复杂度

希尔排序的时间复杂度取决于所选择的间隔序列,它通常介于以下范围:

  1. 最好情况:对于某些特定的间隔序列,希尔排序可以达到O(nlogn) 的时间复杂度,这与快速排序或归并排序相当。

  2. 平均情况:平均情况下,希尔排序的时间复杂度通常被认为是 O(n(logn)2),这比=O(nlogn) 稍差,但仍然比普通插入排序的 𝑂(𝑛^2) 好得多。

  3. 最坏情况:最坏情况下,希尔排序的时间复杂度可以退化到𝑂(𝑛^2),这通常发生在间隔序列选择不佳时。

  4. 实际性能:在实际应用中,希尔排序的性能通常比普通插入排序好,但不如快速排序、堆排序或归并排序。它的实际性能还取决于数据的初始状态和间隔序列的选择。

  5. 间隔序列的影响:不同的间隔序列对希尔排序的性能有很大影响。例如,使用Hibbard 间隔序列或Sedgewick间隔序列可以提高性能,有时甚至可以达到接近 O(nlogn) 的效率。

  6. 空间复杂度:希尔排序是原地排序算法,其空间复杂度为 𝑂(1)。

  7. 稳定性:希尔排序不是稳定的排序算法,这意味着相等的元素在排序后可能会改变它们原来的顺序。

总的来说,希尔排序是一种有效的排序算法,特别是对于中等大小的数据集或者当数据已经部分有序时。然而,对于大型数据集,通常推荐使用其他更高效的排序算法,如快速排序、堆排序或归并排序。

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

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

相关文章

openresty(Nginx) 301重定向域名 http访问强制使用https

1 访问http 2 修改配置访问 server {listen 80;server_name example.cn;return 301 https://$server_name$request_uri;access_log /data/logs/czgzzfjgsup_access.log access;error_log /data/logs/czgzzfjg_error.log error;#location / {root /usr/local/open…

Mac 开发vscode常用命令

1 打开vscode settting配置 commandshiftp 输入&#xff1a;Open User Setting 2

CV预测:快速使用DenseNet神经网络

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…

小规模自建 Elasticsearch 的部署及优化

本文将详细介绍如何在 CentOS 7 操作系统上部署并优化 Elasticsearch 5.3.0,以承载千万级后端服务的数据采集。要使用Elasticsearch至少需要三台独立的服务器,本文所用服务器配置为4核8G的ECS云服务器,其中一台作为 master + data 节点、一台作为 client + data 节点、最后一…

QT——MySQL数据库联用

一、ODBC 1、ODBC简介 ODBC全称为Open Database Connectivity,是一种用于数据库操作的标准接口。要使用ODBC,首先需要安装相应的ODBC驱动程序,然后在系统中配置ODBC数据源。接着,可以通过编程语言(如C++、Java等)或者数据库工具(如SQL Server Management Studio)来连…

Visual Studio Code的安装与配置

Visual Studio Code&#xff08;简称 VS Code&#xff09;是 Microsoft 在2015年4月30日 Build 开发者大会上正式宣布一个运行于 Mac OS X、Windows和 Linux 之上的&#xff0c;针对于编写现代 Web 和云应用的跨平台源代码编辑器&#xff0c;可在桌面上运行&#xff0c;并且可用…

Unity API学习之资源的动态加载

资源的动态加载 在实际游戏开发的更新换代中&#xff0c;随着开发的软件不断更新&#xff0c;我们在脚本中需要拖拽赋值的变量会变空&#xff0c;而要想重新拖拽又太花费时间&#xff0c;因此我们就需要用到Resources.Load<文件类型>("文件名")函数来在一开始…

大模型基础——从零实现一个Transformer(5)

大模型基础——从零实现一个Transformer(1)-CSDN博客 大模型基础——从零实现一个Transformer(2)-CSDN博客 大模型基础——从零实现一个Transformer(3)-CSDN博客 大模型基础——从零实现一个Transformer(4)-CSDN博客 一、前言 上一篇文章已经把Encoder模块和Decoder模块都已…

深度學習筆記12-優化器對比(Tensorflow)

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、我的環境 電腦系統&#xff1a;Windows 10 顯卡&#xff1a;NVIDIA Quadro P620 語言環境&#xff1a;Python 3.7.0 開發工具&…

基于GTX的64B66B编码IP生成(高速收发器二十)

点击进入高速收发器系列文章导航界面 1、配置GTX IP 相关参数 前文讲解了64B66B编码解码原理&#xff0c;以及GTX IP实现64B66B编解码的相关信号组成&#xff0c;本文生成64B66B编码的GTX IP。 首先如下图所示&#xff0c;需要对GTX共享逻辑进行设置&#xff0c;为了便于扩展&a…

【开发工具】git服务器端安装部署+客户端配置

自己安装一个轻量级的git服务端&#xff0c;仅仅作为代码维护&#xff0c;尤其适合个人代码管理。毕竟代码的版本管理是很有必要的。 这里把git服务端部署在centos系统里&#xff0c;部署完成后可以通过命令行推拉代码&#xff0c;进行版本和用户管理。 一、服务端安装配置 …

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 内存访问热度分析(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

windows环境下,怎么查看本机的IP、MAC地址和端口占用情况

1.输入ipconfig,按回车。即查看了IP地址&#xff0c;子码掩码&#xff0c;网关信息。 2.输入ipconfig/all,按回车。即查看了包含IP地址&#xff0c;子码掩码&#xff0c;网关信息以及MAC地址 3.我们有时在启动应用程序的时候提示端口被占用&#xff0c;如何知道谁占有了我们需要…

Vue57-组件的自定义事件_解绑

给谁绑的自定义事件&#xff0c;就找谁去触发&#xff1b;给谁绑的自定义事件&#xff0c;就找谁去解绑&#xff1b; 一、解绑自定义事件 1-1、解绑一个自定义事件 到student.vue组件中去解绑。 1-2、解绑多个自定义事件 使用数组来解绑多个。 1-3、解绑所有的自定义事件 二、…

Android Studio无法连接夜神模拟器的解决方案

一、AS检测不到夜神模拟器 1、问题描述 在按照教程【如何安装和使用Android夜神模拟器】进入夜神的bin目录&#xff0c;输入连接命令回车后&#xff0c;终端显示的already connected to 127.0.0.1:62001&#xff0c;但是AS的Running Devices并没有显示夜神模拟器。 2、解决方…

Arm和高通的法律之争将扰乱人工智能驱动的PC浪潮

Arm和高通的法律之争将扰乱人工智能驱动的PC浪潮 科技行业高管和专家表示&#xff0c;两大科技巨头之间长达两年的法律大战可能会扰乱人工智能驱动的新一代个人电脑浪潮。 上周&#xff0c;来自微软(Microsoft)、华硕(Asus)、宏碁(Acer)、高通(Qualcomm)等公司的高管在台北举行…

计算机毕业设计Python+Vue.js知识图谱音乐推荐系统 音乐爬虫可视化 音乐数据分析 大数据毕设 大数据毕业设计 机器学习 深度学习 人工智能

开发技术 协同过滤算法、机器学习、LSTM、vue.js、echarts、django、Python、MySQL 创新点协同过滤推荐算法、爬虫、数据可视化、LSTM情感分析、短信、身份证识别 补充说明 适合大数据毕业设计、数据分析、爬虫类计算机毕业设计 介绍 音乐数据的爬取&#xff1a;爬取歌曲、…

深度学习推理显卡设置

深度学习推理显卡设置 进入NVIDIA控制面板&#xff0c;选择 “管理3D设置”设置 "低延时模式"为 "“超高”"设置 “电源管理模式” 为 “最高性能优先” 使用锁频来获得稳定的推理 法一&#xff1a;命令行操作 以管理员身份打开CMD查看GPU核心可用频率&…

云计算 | (四)基本云安全

文章目录 📚基本云安全🐇云安全背景🐇基本术语和概念⭐️风险(risk)⭐️安全需求🐇威胁作用者⭐️威胁作用者(threat agent)⭐️匿名攻击者(anonymous attacker)⭐️恶意服务作用者(malicious service agent)⭐️授信的攻击者(trusted attacker)⭐️恶意的内部人员(mal…

有趣且重要的JS知识合集(22)树相关的算法

0、举例&#xff1a;树形结构原始数据 1、序列化树形结构 /*** 平铺序列化树形结构* param tree 树形结构* param result 转化后一维数组* returns Array<TreeNode>*/ export function flattenTree(tree, result []) {if (tree.length 0) {return result}for (const …