插入排序是一种十分简单有效的排序算法,其基本思想就是将每一个待排序的数据按照关键字大小插入前边已经排好序的子序列之中。

文章目录

      • 最基本的插入排序
      • 折半插入排序
      • 希尔排序

最基本的插入排序

插入排序的基本思想如图
在这里插入图片描述
可以看出,不断选中数组中的元素,插入到前边有序队列,其中过程包含了比较从而选择位置,移动数据(因为前边要插入一个元素两个步骤。
以下便是插入排序最基本的代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;void insert_sort(int* a, int n)//不带哨兵的
{for (int i = 1; i < n; i++){if (a[i] < a[i - 1])//升序{int j = i - 1;int key = a[i];//用一个变量保存这次选中的数据,因为他可能会被覆盖while (a[j] > key&&j>=0){a[j + 1] = a[j];//数据后移j--;//一直向前比较}a[++j] = key;}}for (int k = 0; k < n; k++){cout << a[k] << " ";}cout << endl;
}void insert_sort_2(int* a, int n)//默认第一个位置为哨兵位。
{//其实就是把0号位置设置为上边的key的角色for (int i = 2; i < n; i++){if (a[i] < a[i - 1]){a[0] = a[i];int j = 0;for (j = i - 1; a[j] > a[0]; j--){a[j + 1] = a[j];}a[++j] = a[0];}}for (int k = 0; k < n; k++){cout << a[k] << " ";}cout << endl;
}

 其中带不带哨兵位的区别就是是用一个变量来保存此次比较的元素还是用数组第一个元素保存该变量。

折半插入排序

 前边提到插入排序包含比较从而得出此次比较元素的位置,第二步是移动该位置之后的数据。
因为在判定该位置元素的位置时,前边所有的元素已经是有序的了,在有序队列里查找某个元素的位置我们可以立即想到使用折半查找法,从而可以降低比较次数。
下边是折半插入比较的代码

void insert_sort_3(int* a, int n)//默认第一个位置为哨兵位。
{//其实就是把0号位置设置为上边的key的角色int i, j, low, high, mid;for (int i = 2; i < n; i++){a[0] = a[i];low = 1; high = i - 1;//这里在排序时使用折半查找法查找目标位置while (low <= high){mid = (low + high) / 2;if (a[mid] > a[0]){high = mid - 1;}else{low = mid + 1;}}for (j = i - 1; j >= high + 1; --j){a[j + 1]=a[j];}a[high + 1] = a[0];}for (int k = 0; k < n; k++){cout << a[k] << " ";}cout << endl;
}

希尔排序

 上边折半插入排序是通过优化查找当前元素的最终位置来进一步优化插入排序,而希尔排序是通过优化挪动数据的次数和比较的次数来进行优化的。
很多人不太能理解希尔排序到底是怎么优化插入排序这种排序算法的,今天我就按照自己的理解为大家讲解一下。
首先,在普通的插入排序中,每次我们遍历数组的每个元素都可能引起多次查找,虽然可以使用二分查找法优化,但是效率提升不高,而且在查找到该元素应该插入的位置时,还需要大量挪动数据,这就是该算法的弊端之所在。希尔排序最突出的特征就是多出了一个gap变量,即最大步长,允许数据跳跃式移动,这里的思想我觉得更加偏向于交换排序了。
如下图
在这里插入图片描述
第一次时gap设置为n/2,即5,如上图第一躺排序,交换了4和9的位置,直接将元素4跳跃5次,而且该过程只进行了一次比较,同样交换了1和8,在该过程中并没有进行数据的移动,只是进行了比较和交换,如果是普通的插入排序,遍历到1这个位置时一定会挪动很多数据,造成资源浪费。
在第二趟排序时,gap=gap/2。思路和第一趟相同,通过不断地比较和交换达到数组尽可能地有序,从而避免大量挪动数据尽管,尽管折半插入排序已经在查找插入位置时做了优化,但由于其仍需要大量挪动数据,故算法的性能远远比不上希尔排序。
可以看到,当gap为1时,希尔排序就回退成普通的插入排序了,由于数组已经基本有序,所以在最后一趟挪动数据量很小。
希尔排序的时间复杂度依赖于增量函数gap的变化函数,所以分析很难,当n在某特定范围时,时间复杂度约为n的1.3次幂,当某些特殊情况时,gap的变化函数并不适用该数组,在每趟排序时无法有效减少逆序数对时,该算法的时间复杂度降为n的2次幂。同样当数据规模较小,仍然无法直观看出希尔排序的优势。
以下便是希尔排序算法的代码

void shellsort(int* a, int n)//带哨兵位
{//由于某些元素在插入排序时换位置次数很多,所以可以使用分区的方式,使某些位置的元素直接移动长度为dis的距离//起始时设置dis为n/2;//传入的n为排序的数目,实际数组为n+1,由于第一个数组的原因int i, j, k;for ( i = n / 2; i >= 1; i/=2)//i即增量{//在以i为区间的位置上进行插入排序for ( j = i + 1; j <= n; j++)//这里i+1为什么{if (a[j] < a[j - i]){a[0] = a[j];for ( k = j - i; k > 0 && a[0] < a[k]; k -= i){a[k + i] = a[k];}a[k + i] = a[0];}}}for (int k = 0; k < n+1; k++){cout << a[k] << " ";}cout << endl;
}
void shellsort_1(int* a, int n)//不带哨兵位,用key保存值
{//由于某些元素在插入排序时换位置次数很多,所以可以使用分区的方式,使某些位置的元素直接移动长度为dis的距离//起始时设置dis为n/2;int i, j, k;int key;for (i = n / 2; i >= 1; i /= 2)//i即增量{for (j = i; j < n; j++){if (a[j] < a[j - i]){key = a[j];for (k = j - i; k >= 0&&a[k]>a[k+i]; k -= i){a[k + i] = a[k];}a[k + i] = key;}}}for (int k = 0; k < n; k++){cout << a[k] << " ";}cout << endl;
}

 希尔排序十分依赖于其增量序列gap函数,但性能相对较稳定,同时提供了一种全新的排序的思路,还是十分值得学习的。

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

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

相关文章

码农必备!本地调试神器act,GitHub Actions最佳拍档

引言 在现代软件开发实践中&#xff0c;持续集成和持续部署(CI/CD)已成为不可或缺的环节。GitHub Actions 作为 GitHub 官方提供的 CI/CD 解决方案&#xff0c;凭借其与代码仓库的深度集成和丰富的生态系统&#xff0c;获得了广大开发者的青睐。然而&#xff0c;每次修改 CI/C…

大模型本地部署与API服务教程

大模型本地部署与API服务教程 目标&#xff1a;在Ubuntu服务器部署本地大模型&#xff0c;并提供API服务&#xff0c;支持局域网下的Windows客户端调用。 支持两种部署方式&#xff1a;① 自建FastAPI服务&#xff08;高定制&#xff09; ② 使用Ollama&#xff08;极简快速&am…

亚马逊美加站点物流新规解读:库存处理逻辑重构与卖家应对策略

2025年9月&#xff0c;亚马逊美国与加拿大站点即将实施物流计划强制调整&#xff0c;批量清货与捐赠计划的规则迭代&#xff0c;标志着平台对库存生命周期管理的重视程度提升&#xff0c;此次新规以“可持续发展”为核心导向&#xff0c;通过强制与默认参与的双重机制&#xff…

SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序

SpringBoot Web 入门指南&#xff1a;从零搭建第一个SpringBoot程序SpringBoot Web 入门指南&#xff1a;从零搭建第一个SpringBoot程序一、Web开发基础&#xff1a;静态/动态资源与B/S、C/S架构解析​资源类型系统架构二、Spring 与 Spring Boot 核心介绍1. Spring 框架2. Spr…

从图灵完备性到现实差距:为什么你的设备和你本人都潜力无限,却表现各异?

理论上的无限潜力&#xff0c;为何被困在现实的牢笼中&#xff1f;一、引言&#xff1a;一个反直觉的概念 在计算机科学中&#xff0c;图灵完备性&#xff08;Turing Completeness&#xff09; 是衡量一个系统计算能力的黄金标准。它得名于计算机科学之父艾伦图灵&#xff08;A…

Android系统打通HAL层到应用层 --- Framework框架搭建

本文是接续上文&#xff0c;针对于HAL层的接口封装Framework层的接口 HAL层框架搭建&#xff1a;https://blog.csdn.net/m0_50408097/article/details/151148637?spm1001.2014.3001.5502 在 Android 系统架构中&#xff0c;Framework 层&#xff08;框架层&#xff09; 位于 H…

LwIP入门实战 — 2 LwIP概述

目录 2.1 LwIP简介 2.2 LwIP文件架构分析 2.2.1 LwIP软件架构 2.2.2 主要模块划分 2.3 IPC通讯机制 2.4 LwIP的3种编程接口 2.4.1 RAW/Callback API 2.4.2 Netconn API 2.1 LwIP简介 LWIP&#xff08;Light Weight Internet Protocol&#xff0c;轻型网络协议栈&#…

微信小程序-day3

页面导航跳转声明式导航注意&#xff1a;url开头要有/1. 导航到 tabBar 页面2. 导航到非 tabBar 页面3. 后退导航编程式导航跳转传参参数可以在onLoad里用option获取下拉刷新事件可在onPullDownRefresh中定义下拉事件对应操作在其中加入这个函数wx.stopPullDownRefresh()&#…

关于ES中文分词器analysis-ik快速安装

ES中文分词器插件 安装快速安装手动安装 应用ik_max_word 与 ik_smart 的区别验证是否生效 官方地址&#xff1a;https://github.com/infinilabs/analysis-ik 安装 快速安装 插件安装&#xff08;将链接最后的版本号换成当前ES版本号&#xff09;&#xff1a; bin/elastics…

STM32G4 电流环闭环

目录一、STM32G4 电流环闭环1 电流环闭环PID控制2 电流环闭环建模附学习参考网址欢迎大家有问题评论交流 (* ^ ω ^)一、STM32G4 电流环闭环 1 电流环闭环 电流环框图 PID控制 时域和拉普拉斯域的传递函数 PID&#xff1a; P比例部分&#xff0c;I积分部分&#xff0c;D微分…

利用 Java 爬虫获取淘宝商品详情 API 接口

本文将详细介绍如何使用 Java 编写爬虫程序&#xff0c;通过淘宝开放平台的高级版 API 接口获取商品的详细信息。一、淘宝商品详情 API 接口概述淘宝开放平台提供了多个 API 接口用于获取商品的详细信息&#xff0c;其中 taobao.item.get 和 taobao.item.get_pro 是常用的接口。…

idea上传本地项目代码到Gitee仓库教程

前言&#xff1a;本地一个项目代码上传到Gitee仓库1.登录Gitee官网新建仓库&#xff08;命名跟项目同名&#xff09;2.idea添加Gitee插件&#xff08;需要Restart&#xff09;3.idea配置已安装git的路径4.idea添加Gitee账户5.给项目创建Git本地仓库Git仓库创建成功&#xff0c;…

往届生还有机会进入计算机这个行业吗?还能找见好工作吗

前言 最近有很多的往届生来咨询我&#xff0c;问我还能找见工作吗&#xff0c;还能进入这一行吗&#xff08;大多数都是一些24届&#xff0c;考研失败的同学&#xff09; 针对目前这种情况&#xff0c;还能不能进&#xff0c;只能说很难&#xff0c;非常难。 在这里&#xff0c…

Python爬虫实战:研究 Lines, bars and markers 模块,构建电商平台数据采集和分析系统

1. 引言 1.1 研究背景 随着互联网技术的飞速发展,网络上积累了海量的数据资源,这些数据蕴含着丰富的信息和价值。如何高效地获取、处理和分析这些数据,成为信息时代面临的重要课题。Python 作为一种功能强大的编程语言,凭借其丰富的库支持和简洁的语法,在网络数据爬取和…

大文件稳定上传:Spring Boot + MinIO 断点续传实践

文章目录一、引言&#xff1a;问题背景二、技术选型与项目架构三、核心设计与实现1. 初始化上传 (/init)2. 上传分块 (/chunk)3. 完成上传与合并 (/complete)4. 查询上传进度 (/progress)四、断点续传工作流程五、方案优势总结六、拓展优化七、方案优势对比一、引言&#xff1a…

表达式语言EL

表达式语言EL 1.EL表达式的作用 可以说&#xff0c;EL&#xff08;Expression Language&#xff09;表达式语言&#xff0c;就是用来替代<% %>的&#xff0c;EL比<%%>更简洁&#xff0c;更方便。 2.与请求参数有关的内置对象 1.使用表达式&#xff1a;<%request…

pycharm无法添加本地conda解释器/命令行激活conda时出现很多无关内容

本文主要解决以下两种问题&#xff1a;1.pycharm在添加本地非base环境时出现无法添加的情况&#xff0c;特征为&#xff1a;正在创建conda解释器--->弹出一个黑窗口又迅速关闭&#xff0c;最终无法添加成功2.在conda prompt中进行activate 指定env&#xff08;非base&#x…

LeetCode 844.比较含退格的字符串

给定 s 和 t 两个字符串&#xff0c;当它们分别被输入到空白的文本编辑器后&#xff0c;如果两者相等&#xff0c;返回 true 。# 代表退格字符。 注意&#xff1a;如果对空文本输入退格字符&#xff0c;文本继续为空。 示例 1&#xff1a; 输入&#xff1a;s “ab#c”, t “a…

什么是涌浪电压

涌浪电压&#xff08;浪涌电压&#xff09;是电路或设备在运行时突然出现的、超出额定电压的瞬时过电压。它通常由雷击、电感性负载的断开、电力系统的故障切换或大型电容性负载的接通等原因引起。涌浪电压是一种高能量的瞬变干扰&#xff0c;可能损坏电子设备&#xff0c;如击…

uniapp 优博讯k329蓝牙打印机,设置打印机,一键打印

设置页面&#xff1a;<template><view class"pageBg"><u-navbar leftIconColor"#fff" :leftIconSize"28" title"打印设置" bgColor"#3c9cff" :placeholder"true"leftClick"$navigateBack&quo…