【八大经典排序算法】:直接插入排序、希尔排序实现 ---> 性能大比拼!!!

【八大经典排序算法】:直接插入排序、希尔排序实现 ---> 性能大比拼!!!

  • 一、 直接插入排序
      • 1.1 插入排序原理
      • 1.2 代码实现
      • 1.3 直接插入排序特点总结
  • 二、希尔排序 ( 缩小增量排序 )
      • 2.1 希尔排序原理
      • 2.2 代码实现
      • 2.3 希尔排序特点总结
  • 三、直接插入排序和希尔排序性能大比拼 !!!
      • 3.1 如何对比性能?准备工作
      • 3.2 如何实现?
        • 创建数据
        • 比较快慢
        • 代码、结果分析


一、 直接插入排序

1.1 插入排序原理

直接插入排序是一种简单的插入排序法,其基本原理是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
 
在这里插入图片描述
而实际中我们玩扑克牌时,就用了插入排序的思想
在这里插入图片描述


1.2 代码实现

【代码思路】:直接插入排序还是比较简单的。我们将第一个元素当作一个有序序列,然后从第二个元素开始,将其作为当前插入的元素,并与已排序部分的元素进行比较,找到合适的插入位置。然后不断重复上述操作,直到所有元素都被插入到已排序部分。
 
当插入第i(i>=1)个元素时,前面的a[0], a[1], …, a[i-1]已经排好序,此时用a[i]的排序码与a[i-1],a[i-2],…的排序码顺序进行比较,找到插入位置即将a[i]插入,原来位置上的元素顺序后移。

void InsertSort(int* a, int n)//排升序
{for (int i = 0; i < n-1; i++){int end = i;//tmp记录待插入元素,因为插入数据时需要挪动数据,会被覆盖int tmp = a[end+1];//[0,end]有序,将tmp插入到合适位置while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}

1.3 直接插入排序特点总结

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高。
  2. 时间复杂度:O(N^2)。并且是时间复杂度为 N^2的所有算法中最快的排序。
  3. 空间复杂度:O(1),它是一种稳定的排序算法。

二、希尔排序 ( 缩小增量排序 )

逆序有序的数组进行插入排序时,时间复杂度为O ( n^2 ),此时效率最低。

​ 顺序有序的数组进行插入排序时,时间复杂度为O ( n ),此时效率最高。

​我们发现,当被排序的对象越接近有序时,插入排序的效率越高,那我们是否有办法将数组变成接近有序后再用插入排序,此时希尔大佬就发现了这个排序算法,并命名为希尔排序


2.1 希尔排序原理

希尔排序法又称缩小增量法。为了提高插入排序效率,希尔给出了这样一个办法:
将原有大量数据进行分组,分割成若干个子序列,此时每个子序列待排序的个数就减少了。然后对这些子序列分别进行插入排序(目的在于使较小的数据基本在前面,较大的数据基本在后面,而不大不小的数据则位于中间,从而达到排序基本有序的目的)。当整个序列基本有序时,最后在全体进行一次插入排序即可。


2.2 代码实现

【代码思路】:首先确定希尔排序的间距(gap),可以根据不同的方法选择不同的间距。根据选择的间距,将待排序的数组分割成若干个子序列,使用插入排序对每个子序列进行排序。逐步减小间距,重复第二步,直到间距为1。此时,整个数组被分割成了一个子序列,即原始的待排序序列。最后对原始的待排序序列进行插入排序,最终得到有序数组。(这里博主建议gap=n(数据个数)/ 3,在不断更新gap)

在这里插入图片描述

void ShellSort(int* a, int n)
{//1. gap>1 预排序//2. gap=1 插入排序int gap = n;while (gap > 1){gap = gap / 3 + 1;//多组并排for (int j = 0; j < n - gap; j++){int end = j;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;}}
}

2.3 希尔排序特点总结

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:
    《数据结构(C语言版)》— 严蔚敏
    在这里插入图片描述
    《数据结构-用面相对象方法与C++描述》— 殷人昆
    在这里插入图片描述
    因为此处的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照:O(n^1.25) ~ O(1.6 * n^1.25)。

三、直接插入排序和希尔排序性能大比拼 !!!

希尔排序虽然看起来比较普通,但实际性能可以和快排以及堆排序达到一个量级!!!

3.1 如何对比性能?准备工作

要对比两算法性能,首先创建一个包含大量元素的随机数组,这个数组将用于测试两个排序算法的效率。并且要确保测试数据集的大小足够大,以便能够准确测量算法的效率。在分别对两个排序算法在相同的测试数据集上进行排序,并记录每个算法排序所花费的时间。最后将两个排序算法的排序时间进行比较即可
 
Tips:
①:在对比两个排序算法的效率时,需要确保使用相同的编程语言和相同的测试数据集。
②::编译器切换到Release模式。
在这里插入图片描述
至于原因就得提到Release的特点了。
Release模式可以优化代码的性能和执行速度,减少调试信息的冗余,并提高程序的运行效率。在对比两个算法时,这些优化和调试信息并不是必需的。


3.2 如何实现?

创建数据

首先为两个为两个待排序数组创建足够大的存储空间,然后调用rand()随机生成数据。为保证两待排数组中的数据一样,将随机生成的数据依次赋值给两数组。

比较快慢

要比较两则运行时间,可以调用clock()函数,就可以轻松得到算法执行时间了!!
 
CPlusPlus:clock()
(clock()计算的是程序运行开始到执行此函数的运行时间,单位ms)

代码、结果分析

void TestOP()
{srand((unsigned int)time(NULL));//博主受限电脑配置,数据只能建10000个。//各位可适当扩大数据,两则差距更明显const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);free(a1);free(a2);
}

运行结构:
在这里插入图片描述
上述结果我们直观发现,希尔排序性能远远大于直接插入排序。
可能有部分学者还是感受不出来,你可以将数据个数扩大到百万看看就知道了。


在这里插入图片描述
在这里插入图片描述

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

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

相关文章

数据可视化、BI和数字孪生软件:用途和特点对比

在现代企业和科技领域&#xff0c;数据起着至关重要的作用。为了更好地管理和理解数据&#xff0c;不同类型的软件工具应运而生&#xff0c;其中包括数据可视化软件、BI&#xff08;Business Intelligence&#xff09;软件和数字孪生软件。虽然它们都涉及数据&#xff0c;但在功…

文献阅读:Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

文献阅读&#xff1a;Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 1. 文章简介2. 具体方法3. 实验结果 1. 数学推理 1. 实验设计2. 实验结果3. 消解实验4. 鲁棒性考察 2. 常识推理 1. 实验设计2. 实验结果 3. 符号推理 1. 实验设计2. 实验结果 4.…

华为数通方向HCIP-DataCom H12-821题库(单选题:241-260)

第241题 ​​LS Request​​报文不包括以下哪一字段? A、通告路由器(Advertising Router) B、链路状态 ID (Link Srate ID) C、数据库描述序列号(Database Dascription Sequence lumber) D、链路状态类型 Link state type) 答案:C 解析: LS Request 报文中包括以下字段…

协议定制 + Json序列化反序列化

文章目录 协议定制 Json序列化反序列化1. 再谈 "协议"1.1 结构化数据1.2 序列化和反序列化 2. 网络版计算器2.1 服务端2.2 协议定制(1) 网络发送和读取的正确理解(2) 协议定制的问题 2.3 客户端2.4 代码 3. Json实现序列化反序列化3.1 简单介绍3.2 使用 协议定制 J…

【送书活动】揭秘分布式文件系统大规模元数据管理机制——以Alluxio文件系统为例

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

python调用GPT实现:智能用例生成工具

工具作用&#xff1a; 根据输入的功能点&#xff0c;生成通用测试点 实现步骤 工具实现主要分2个步骤&#xff1a; 1.https请求调用Gpt,将返回响应结果保存为.md文件 2.用python实现 将 .md文件转换成.xmind文件 3.写个简单的前端页面&#xff0c;调用上述步骤接口 详细代…

操作系统强化认识之Shell编程学习与总结

目录 1.Shell的概述 2.Shell脚本入门 3.变量 3.1.系统预定义变量 3.2.自定义变量 3.3.特殊变量 4.运算符 5.条件判断 6.流程控制 6.1.if判断 6.2.case语句 6.3.for循环 6.4.while循环 7.read读取控制台输入 8.函数 8.1.系统函数 8.2.自定义函数 9.正则表示式入…

【C++入门到精通】C++入门 ——搜索二叉树(二叉树进阶)

阅读导航 前言一、搜索二叉树简介1. 概念2. 基本操作⭕搜索操作&#x1f36a;搜索操作基本代码&#xff08;非递归&#xff09; ⭕插入操作&#x1f36a;插入操作基本代码&#xff08;非递归&#xff09; ⭕删除操作&#x1f36a;删除操作基本代码&#xff08;非递归&#xff0…

MySQL无法查看系统默认字符集以及校验规则

show variables like character_set_database; show variables like collation_database;这个错误信息表示MySQL在尝试访问performance_schema.session_variables表时&#xff0c;发现该表不存在。这个问题可能是由于MySQL的版本升级导致的。解决这个问题的一种方法是运行mysql…

论文浅尝 | 训练语言模型遵循人类反馈的指令

笔记整理&#xff1a;吴亦珂&#xff0c;东南大学硕士&#xff0c;研究方向为大语言模型、知识图谱 链接&#xff1a;https://arxiv.org/abs/2203.02155 1. 动机 大型语言模型&#xff08;large language model, LLM&#xff09;可以根据提示完成各种自然语言处理任务。然而&am…

Java JUC 并发编程(笔记)

文章目录 再谈多线程并发与并行顺序执行并发执行并行执行 再谈锁机制重量级锁轻量级锁偏向锁锁消除和锁粗化 JMM内存模型Java内存模型重排序volatile关键字happens-before原则 多线程编程核心锁框架Lock和Condition接口可重入锁公平锁与非公平锁 读写锁锁降级和锁升级 队列同步…

[构建 Vue 组件库] 小尾巴 UI 组件库 —— 横向商品卡片(仿淘宝)

文章归档于&#xff1a;https://www.yuque.com/u27599042/row3c6 组件库地址 npm&#xff1a;https://www.npmjs.com/package/xwb-ui?activeTabreadmegitee&#xff1a;https://gitee.com/tongchaowei/xwb-ui 下载 npm i xwb-ui配置 按需导入 import {组件名 } from xwb-…

【Unity】 2D 游戏 库存模块实现

库存模块主要参考了 youtube 上的视频 BMo 的 Flexible INVENTORY SYSTEM in Unity with Events and Scriptable Objects 和 Simple Inventory UI in Unity With Grid Layouts 这两个视频是一个系列 还是一个视频也是 BMo的 How To INTERACT with Game Objects using UNITY E…

Nginx详解 第五部分:Ngnix反向代理(负载均衡 动静分离 缓存 透传 )

Part 5 一、正向代理与反向代理1.1 正向代理简介1.2 反向代理简介 二、配置反向代理2.1 反向代理配置参数2.1.1 proxy_pass2.1.2 其余参数 2.2 配置实例:反向代理单台web服务器2.3 代理转发 三、反向代理实现动静分离四、缓存功能五、反向代理客户端的IP透传5.1 原理概述5.2 一…

谁在为网络安全制造标尺?

“我们想帮助企业往后退一步&#xff0c;去全局的看一下自己的安全能力建设水平如何&#xff0c;以及在当下的阶段最应该做的安全建设是什么&#xff1f; ” 度量&#xff0c;对应的是更清晰的认知。而对企业安全而言&#xff0c;这种认知&#xff0c;也更在成为一把新的标尺…

Redis带你深入学习数据类型set

目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令&#xff1a;sinter、sinterstore、sunion、sunionstore、s…

CSS:屏幕正中间有个元素A,元素A中有文字A,随着屏幕宽度的增加

始终需要满足以下条件&#xff1a; A元素垂直居中于屏幕***&#xff1b;A元素距离屏幕左右边距各10px&#xff1b;A元素里面的文字”A”的font-size:20px&#xff1b;水平垂直居中;A元素的高度始终是A元素宽度的50%; (如果搞不定可以实现为A元素的高度固定为200px;)请用 html及…

【Unity基础】3.脚本控制物体运动天空盒

【Unity基础】3.脚本控制物体运动&天空盒 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;搭建开发环境 &#xff08;1&#xff09;下载visual studio 在我们下载unity编译器的时候&…

Microsoft Edge网页视频播放绿屏解决方法(B站)

一&#xff1a;问题&#xff0c;在B站观看视频时有绿色条纹 二&#xff1a;查找原因&#xff0c;未知 三&#xff1a;解决方法 三.1网页设置关闭硬件加速 三.2 点击视频播放下的 “小齿轮”&#xff0c;然后点击“更多播放设置” 把播放策略 “默认” 改为“AVC” 四&…

Tomcat配置域名和端口

Tomcat配置域名和端口 1.进入tomcat文件夹2. cd 到你的tomcat下3. 修改server.xml文件中监听端口4. 重启tomcat 1.进入tomcat文件夹 2. cd 到你的tomcat下 3. 修改server.xml文件中监听端口 继续修改server.xml中Host 4. 重启tomcat 进入bin ./shutdown.sh ./startup.sh …