数据结构——排序算法——希尔排序

希尔排序本质上是对插入排序的一种优化,它利用了插入排序的简单,又克服了插入排序每次只交换相邻两个元素的缺点。它的基本思想是:

1.将待排序数组按照一定的间隔分为多个子数组,每组分别进行插入排序。这里按照间隔分组指的不是取连续的一段数组,而是每跳跃一定间隔取一个值组成一组
2.逐渐缩小间隔进行下一轮排序
3.最后一轮时,取间隔为 1,也就相当于直接使用插入排序。但这时经过前面的「宏观调控」,数组已经基本有序了,所以此时的插入排序只需进行少量交换便可完成。

举个例子,对数组 [84,83,88,87,61,50,70,60,80,99]进行希尔排序的过程如下:

请添加图片描述
1.第一遍(5 间隔排序):按照间隔 5 分割子数组,共分成五组,分别是[84,50],[83,70],[88,60],[87,80],[61,99]。对它们进行插入排序,排序后它们分别变成: [50,84],[70,83],[60,88],[80,87],[61,99],此时整个数组变成 [50,70,60,80,61,84,83,88,87,99]

2.第二遍(2 间隔排序):按照间隔2 分割子数组,共分成两组,分别是 [50,60,61,83,87],[70,80,84,88,99]。对他们进行插入排序,排序后它们分别变成:[50,60,61,83,87],[70,80,84,88,99],此时整个数组变成 [50,70,60,80,61,84,83,88,87,99]。这里有一个非常重要的性质:当我们完成 2 间隔排序后,这个数组仍然是保持 5 间隔有序的。也就是说,更小间隔的排序没有把上一步的结果变坏

3.第三遍(1 间隔排序,等于直接插入排序):按照间隔 1 分割子数组,分成一组,也就是整个数组。对其进行插入排序,经过前两遍排序,数组已经基本有序了,所以这一步只需经过少量交换即可完成排序。排序后数组变成[50,60,61,70,80,83,84,87,88,99],整个排序完成。

 void shellSort(vector<int> arr) {// 间隔序列,在希尔排序中我们称之为增量序列for (int gap = arr.size() / 2; gap > 0; gap /= 2) {// 分组for (int groupStartIndex = 0; groupStartIndex < gap; groupStartIndex++) {// 插入排序for (int currentIndex = groupStartIndex + gap; currentIndex < arr.size(); currentIndex += gap) {// currentNumber 站起来,开始找位置int currentNumber = arr[currentIndex];int preIndex = currentIndex - gap;while (preIndex >= groupStartIndex && currentNumber < arr[preIndex]) {// 向后挪位置arr[preIndex + gap] = arr[preIndex];preIndex -= gap;}// currentNumber 找到了自己的位置,坐下arr[preIndex + gap] = currentNumber;}}}
}

优化

 void shellSort(vector<int> arr) {// 间隔序列,在希尔排序中我们称之为增量序列for (int gap = arr.size() / 2; gap > 0; gap /= 2) {// 从 gap 开始,按照顺序将每个元素依次向前插入自己所在的组for (int i = gap; i < arr.size(); i++) {// currentNumber 站起来,开始找位置int currentNumber = arr[i];// 该组前一个数字的索引int preIndex = i - gap;while (preIndex >= 0 && currentNumber < arr[preIndex]) {// 向后挪位置arr[preIndex + gap] = arr[preIndex];preIndex -= gap;}// currentNumber 找到了自己的位置,坐下arr[preIndex + gap] = currentNumber;}}
}

使用 Knuth 序列进行希尔排序的代码

void shellSortByKnuth(vector<int> arr) {// 找到当前数组需要用到的 Knuth 序列中的最大值int maxKnuthNumber = 1;while (maxKnuthNumber <= arr.size() / 3) {maxKnuthNumber = maxKnuthNumber * 3 + 1;}// 增量按照 Knuth 序列规则依次递减for (int gap = maxKnuthNumber; gap > 0; gap = (gap - 1) / 3) {// 从 gap 开始,按照顺序将每个元素依次向前插入自己所在的组for (int i = gap; i < arr.size(); i++) {// currentNumber 站起来,开始找位置int currentNumber = arr[i];// 该组前一个数字的索引int preIndex = i - gap;while (preIndex >= 0 && currentNumber < arr[preIndex]) {// 向后挪位置arr[preIndex + gap] = arr[preIndex];preIndex -= gap;}// currentNumber 找到了自己的位置,坐下arr[preIndex + gap] = currentNumber;}}
}

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

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

相关文章

vscode搭建Django自带后台管理系统

文章目录 一、django自带的后台管理系统1. 建表2. 后台管理系统2.1 创建账号2.2 运行后台2.3 登录 二、模版渲染1. 直接将数据渲染到页面2. 数据传递给js 三、数据库1. 查看当前数据库2. 创建UserInfo数据表3. Django rest framework配置 四、vue前端搭建1. 在Django项目的根目…

k8s(Kubernetes)集群部署--使用 kubeadm方式部署

k8s集群部署--使用 kubeadm方式部署 一、测试所需环境&#xff08;三台均要执行&#xff09;二、配置准备&#xff08;三台均要执行&#xff09;1. 重命名hostname、添加hosts2. 关闭防火墙、selinux与swap3. 添加网桥过滤及内核转发配置文件4.同步时间5.安装ipset及ipvsadm 三…

yocto stm32mp1集成ros

yocto stm32mp1集成ros yocto集成ros下载meta-rosyocto集成rosrootfs验证 yocto集成ros 本章节介绍yocto如何集成ros系统用来作机器人开发。 下载meta-ros 第一步首先需要下载meta-ros layer&#xff0c;meta-ros的链接如下&#xff1a;https://github.com/ros/meta-ros/tre…

1-4 AUTOSAR方法论

总目录——AUTOSAR入门详解AUTOSAR入门详解目录汇总&#xff1a;待续中。。。https://xianfan.blog.csdn.net/article/details/132818463 目录 一、前言 二、方法论 三、单个ECU开发流程 一、前言 汽车生产供应链上有以下角色&#xff1a;OEM、TIER1、TIER2&#xff0c;其主…

《向量数据库指南》——哪些需求推动了如Milvus Cloud等的向量数据库的更新和迭代?

这个问题需要深入讨论大模型与向量数据库之间的关系。从去年 ChatGPT 推出时这个问题就开始引发我们的思考。在当时,我们敏锐地意识到这将是一个机遇。然而,在国内,这个概念的认知需要更长的时间。我个人在去年四五月份的美国之行中注意到,数据库在美国已经是一个非常热门的…

入门人工智能 ——使用 tensorflow 训练一个新闻分类模型(6)

入门人工智能 ——使用 tensorflow 训练一个新闻分类模型&#xff08;6&#xff09; 入门人工智能 ——使用 tensorflow 训练一个新闻分类模型使用 tensorflow 训练一个新闻分类模型1. 安装TensorFlow和所需的依赖项。2. 打开收集的新闻数据集构建模型模型训练模型评估保存模型…

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一)

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一) 第一部分:组态配置 具体步骤可参考以下内容: 如下图所示,新建一个项目后,添加一个安全型PLC,这里以1516F-3 PN/DP为例进行说明, 如下图所示,添加CPU完成后,可以看到左侧的项目树中比普通的PLC多了几个选项…

MySQL-DDL语句

MySQL-DDL语句 数据库操作语句增删数据库查看数据库列表创建数据库进入&#xff08;使用&#xff09;数据库/查看当前所在的数据库查看数据库的建库语句查看数据库的编码集和校验集删除数据库修改数据库的编码集查看数据库支持的编码集和校验集 数据库备份备份单个数据库恢复数…

rust编译出错:error: failed to run custom build command for `ring v0.16.20`

安装 Visual Studio&#xff0c;确保选择 —.NET 桌面开发、使用 C 的桌面开发和通用 Windows 平台开发。显示已安装的工具链rustup show。然后通过运行更改和设置工具链rustup default stable-x86_64-pc-windows-msvc。 另外是想用clion进行调试rust 需要你按下面配置即可解…

solidworks底部状态栏显示不出来

如下图所示&#xff0c;solidworks主界面下面的状态栏突然不见了。 怎么调出来&#xff1f; 第一步&#xff1a;点击视图菜单&#xff0c;用户界面&#xff0c;把状态栏前的勾勾上。 第二步&#xff1a;把视图下面的触摸模式关掉&#xff0c;这一点很容易被大家忽略。

Oracle(1):Oracle简介

1 什么是 ORACLE ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一。 ORACLE 通常应用于大型系统的数据库产品。 ORACLE 数据…

全面详解Maven的配置文件pom.xml(含常用plugin)

系列文章目录 手把手教你maven的安装与配置(windows) 全面详解Maven的配置文件pom.xml&#xff08;含常用plugin&#xff09; 系列文章目录一、什么是pom.xml二、pom.xml的结构三、项目的基本信息1.modules2.parent3.scm4.properties 四、项目的依赖列表1.dependency2.reposit…

【服务器 | 测试】如何在centos 7上面安装jmeter

安装之前需要几个环境&#xff0c;以下是列出的几个环境 CentOS 7.7 64位JDK 1.8JMeter 5.2 1. 下载jmeter安装包 JMeter是开源的工具&#xff0c;安装 JMeter 要先安装好 JDK 的环境&#xff0c;安装JDK在前面的文章已经讲到 JMeter最新版下载地址&#xff1a;Apache JMeter…

X86_64函数调用汇编程序分(2)

X86_64函数调用汇编程序分&#xff08;2&#xff09; 1 X86_64寄存器使用标准2 leaveq和retq指令2.1 leaveq2.2 retq 3 执行leaveq和retq之后栈的结构3.1 执行leaveq之后栈的结构3.1.1 test_fun_b函数执行leaveq之前的栈结构示意图3.1.2 test_fun_b函数执行leaveq之后的栈结构示…

JSP SSM 成果展示系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP SSM 冬奥建设成果展示系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的 源代码和数据库&#xff0c;系统主…

ubuntu基本配置

记录一下每次重新安装系统之后都要进程的操作 更新源 更新源的教程 sudo bash -c "cat << EOF > /etc/apt/sources.list && apt update deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src http://mirrors.a…

LLM - 数据处理之 Process Dataset For LLM With PT、SFT、RM

目录 一.引言 二.PT 数据流程 1.数据样式 2.生成代码 3.数据生成 三.SFT 数据流程 1.数据样式 2.生成代码 3.数据生成 四.RM 数据流程 1.生成逻辑 2.RM 模型测试 五.总结 一.引言 上篇文章 LLM - 批量加载 dataset 并合并介绍了如何加载多个文件并合成一个 datas…

leetcode:67. 二进制求和

题目&#xff1a; 函数原型&#xff1a; char * addBinary(char * a, char * b) 思路&#xff1a; 二进制相加&#xff0c;首先我们考虑先将字符串逆序。由此要写一个逆序函数reserve。字符串逆序后&#xff0c;从前往后相加&#xff0c;以较长的字符串的长度为标准长度n&#…

【光谱超分辨率:综述】

Spectral super-resolution meets deep learning: Achievements and challenges &#xff08;面向深度学习的光谱超分辨率&#xff1a;成就和挑战&#xff09; 光谱超分辨率是一种从RGB图像获取高光谱图像的重要技术&#xff0c;可以有效地克服高光谱图像获取成本高、空间分辨…

vite + react + typescript + uni-app + node 开发一个生态系统

简介 使用 vite react typescript uni-app node 来开发一个简易的生态系统案例&#xff0c;包含 APP&#xff0c;H5&#xff0c;微信小程序&#xff0c;控制台&#xff0c;服务端 开发 admin 技术栈&#xff1a;vite react typescript初始化控制台项目选择自定义预设…