经典排序算法之希尔排序|c++代码实现||什么是希尔排序|如何代码实现

引言

排序算法c++实现系列第4弹——希尔排序

算法介绍

希尔排序(Shell Sort),也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。该排序算法的基本思想是将原始序列分成若干个子序列,分别对每个子序列进行直接插入排序,然后逐步缩小子序列的间隔,直到整个序列变成一个有序序列。

算法步骤

  1. 选择增量序列:选择一个增量序列(即代码中的gap),通常以2为基数,逐步缩小增量的值(即希尔增量序列)。增量序列的选择对希尔排序的性能影响很大,常见的增量序列包括希尔增量序列、Hibbard增量序列、Sedgewick增量序列等。

    1. 希尔增量序列(Shell's Increment Sequence): 希尔增量序列是希尔排序的名字来源之一。希尔增量序列是通过h_k = n / 2^k计算得到的,其中(n)为序列长度,(k)为增量的序号。希尔增量序列的第一个增量通常为序列长度的一半,随后的增量依次减半,直到增量为1。希尔增量序列的优点是简单易于实现,但其性能较差,不如其他增量序列。

    2. Hibbard增量序列: Hibbard增量序列是由Donald Hibbard于1963年提出的一种增量序列。Hibbard增量序列的计算公式为(h_k = 2^k - 1),其中(k)为增量的序号。Hibbard增量序列的特点是每个增量都是连续的奇数,并且增量递减非常快。Hibbard增量序列的性能相对较好,但增量之间的差异较大,可能导致不稳定的性能。

    3. Sedgewick增量序列: Sedgewick增量序列是由Robert Sedgewick于1986年提出的一种增量序列。:Sedgewick增量序列的特点是增量之间的差异较小,性能稳定,并且在实际应用中表现优秀。(在代码中也已实现)

  2. 分组排序:根据选定的增量序列,将原始序列分成若干个子序列,对每个子序列进行直接插入排序。

  3. 缩小增量:逐步缩小增量的值,重复第二步的分组排序过程,直到增量为1。

  4. 最终排序:当增量为1时,即对整个序列进行一次直接插入排序,最终得到排序好的序列。

举例说明:如代码中的数组arr = {61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62};我们假设此时gap为2,那么原数据就将被分为

子序列1:{61, 29, 34, 72, 50, 62};子序列2:{17, 22, 60, 21, 1};分别对上述两个子序列进行直接插入排序后得到全部数据序列为:{29, 1, 34, 17, 50, 21, 61, 22, 62, 60, 72};

接下来,可以使gap为1,相当于对{29, 1, 34, 17, 50, 21, 61, 22, 62, 60, 72}整体做一次直接插入排序,即得到最终结果

时间复杂度

希尔排序的时间复杂度取决于增量序列的选择,最坏情况下的时间复杂度为 O(n2),平均情况下为 O(nlog2n)

代码实现

#include<bits/stdc++.h>
using namespace std;
template<typename T>
void shell_sort(T arr[], int len) {
//	// 希尔增量序列
//	int gap = len / 2;
//	while (gap) {
//		for (int i = gap; i < len; i++) {
//			int j = i - gap;
//			T k = arr[i];
//			while ((j >= 0) && (arr[j] > k)) {
//				arr[j + gap] = arr[j];
//				j -= gap;
//			}
//			arr[j + gap] = k;
//		}
//		gap /= 2;
//	}
	// Sedgewick增量序列
	int gap = 1;
	while (gap < len / 3) {
		gap = 3 * gap + 1;
	}
	while (gap) {
		for (int i = gap; i < len; i++) {
			T key = arr[i];
			int j = i - gap;
			while (arr[j] > key && (j >= 0)) {
				arr[j + gap] = arr[j];
				j -= gap;
			}
			arr[j + gap] = key;
		}
		gap /= 3;
	}

}
int main() {
	int arr[] = {61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62};
	int len = (int) sizeof(arr) / sizeof(*arr);
	shell_sort(arr, len);
	for (int i = 0; i < len; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;

	float arrf[] = {17.5, 19.1, 0.6, 1.9, 10.5, 12.4, 3.8, 19.7, 1.5, 25.4, 28.6, 4.4, 23.7, 5.4};
	int lenf = sizeof(arrf) / sizeof(*arrf);
	shell_sort(arrf, lenf);
	for (int i = 0; i < lenf; i++) {
		cout << arrf[i] << " ";
	}
	return 0;
}

运行结果展示:

如果对您有启发的话,欢迎点赞加收藏

其他排序算法实现

经典排序算法之插入排序|c++实现|什么是插入排序|如何代码实现-CSDN博客

排序算法之选择排序|c++实现-CSDN博客

 经典排序算法之冒泡排序|c++代码实现-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新质生产力助春播春管:佳格天地连续第5年上线大数据平台,服务春季生产

随着“惊蛰”节气过去,全国各地陆续掀起春播春管热潮。今年的政府工作报告中指出,2023年我国粮食产量1.39万亿斤,再创新高。2024年要坚持不懈抓好“三农”工作,扎实推进乡村全面振兴,粮食产量预期目标1.3万亿斤以上。 粮食产量预期目标的明确为一年农事生产指引了方向。同时,新…

SpringBoot第三课-日志

1.日志分类 2.默认使用 默认使用logback与slf4j作为底层默认日志 但是由于日志是系统启动就需要使用&#xff0c;所以与其他的自动配置不同&#xff0c;自动配置是后来使用的&#xff0c;而日志是使用监听器配置好的。 ApplicationListener 3.日志级别 1.级别介绍 SpringB…

企业为什么要发新闻稿?新闻发稿怎么做?

在当今信息流的时代&#xff0c;新闻稿作为企业传递信息、展示形象的重要工具&#xff0c;发挥着举足轻重的作用。那么&#xff0c;企业为何要发布新闻稿呢&#xff1f;本文将从宣传内容、品牌价值、传播效果、权威性和持久性等方面&#xff0c;深入探讨企业发布新闻稿的必要性…

回溯算法题解(难度由小到大)(力扣,洛谷)

目录 注意&#xff1a; P1157 组合的输出&#xff08;洛谷&#xff09;https://www.luogu.com.cn/problem/P1157int result[10000] { 0 }; 216. 组合总和 IIIhttps://leetcode.cn/problems/combination-sum-iii/ 17. 电话号码的字母组合https://leetcode.cn/problems/lett…

文献学习-13-机器人顶刊IJRR近期国人新作(2024.3)

一、IJRR简介 The International Journal of Robotics Research&#xff08;IJRR&#xff09;是机器人领域的高水平学术期刊&#xff0c;专注于发布关于机器人技术和相关领域的最新研究成果。IJRR创刊于1982年&#xff0c;是该领域的第一本学术刊物&#xff0c;2022-2023最新影…

qnx启动中控屏黑屏

bmetrics_service boot metrics service, 用于记录统计启动性能信息,读取/dev/bmetrics可以获取到这些信息 # use memorydump memorydump Sets the debug cookies, copies MMU info into reset_info asinfo, sets the secure monitor(TZ) dump buffer, starts tracelogger Usa…

消息队列-Kafka-消费方如何分区与分区重平衡

消费分区 资料来源于网络 消费者订阅的入口&#xff1a;KafkaConsumer#subscribe 消费者消费的入口&#xff1a;KafkaConsumer#poll 处理流程&#xff1a; 对元数据重平衡处理&#xff1a;KafkaConsumer#updateAssignmentMetadataIfNeeded 协调器的拉取处理&#xff1a;onsum…

Fiddler抓包丨最常用功能实战演练

Fiddler中常用的功能如下&#xff1a; 停止抓包清空会话窗内容过滤请求解码设置断点 一. 停止抓包 二. 清空会话窗 方法一&#xff0c;工具栏工具&#xff1a; 方法二&#xff0c;命令行形式&#xff1a; 当然&#xff0c;命令行工具也还支持其他命令的输入&#xff0c;这里不…

【C++】设计模式:建造者、原型、单例

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍设计模式&#xff1a;建造者、原型、单例。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xf…

接口自动化测试用例的编写方法

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 phpunit 接口自动化测试系列 Post接口自动化测试用例 Post方式…

Java使用spire.doc操作word文档(合并、插入文字图片和表格、替换书签)

一、引入依赖 <dependency><groupId>e-iceblue</groupId><artifactId>spire.office</artifactId><version>7.5.4</version> </dependency> 二、word操作 1、合并word文档 import com.spire.doc.Document; import com.spir…

java多线程实现同步的方式介绍

在 Java 多线程编程中&#xff0c;同步是确保多个线程在访问共享资源时的正确性和一致性的重要机制。Java 提供了多种方式来实现线程同步&#xff0c;每种方式都有其特点和适用场景。以下是一些常见的同步方式及其特点和应用场景&#xff0c;以及简单的例子来说明它们的用法。 …

从零开始的LeetCode刷题日记:142.环形链表II

一.相关链接 视频链接&#xff1a;代码随想录&#xff1a;142.环形链表II 题目链接&#xff1a;142.环形链表II 二.心得体会 这道题是一道链表题&#xff0c;但他没有对头结点的操作&#xff0c;所以不用虚拟头结点。这道题要分两步进行&#xff0c;第一步是判断链表有没有环…

win11修改主机mac地址

很多时候&#xff0c;为了限制恶意的蹭流浪&#xff0c;除了分配固定的ip地址外&#xff0c;还限制mac地址。只有mac与ip一致&#xff0c;才能上网冲浪 网络适配器中修改 搜索“控制面板”打开 控制面板 > 网络和Internet > 网络和共享中心 >查看网络状态和任务>…

Redis什么这么快和Redis单线程模型和多线程

概述 1、完全基于内存&#xff0c;绝大部分请求是纯粹的内存操作&#xff0c;非常快速。数据存在内存中&#xff0c;类似于HashMap&#xff0c;HashMap的优势就是查找和操作的时间复杂度都是O(1)&#xff1b; 2、数据结构简单&#xff0c;对数据操作也简单&#xff0c;Redis中…

测试常用的Linux命令

前言 直接操作硬件 将把操作硬件的代码封装成系统调用&#xff0c;供程序员使用 虚拟机软件 可以模拟的具有完整硬件系统的功能 可以在虚拟机上安装不同的操作系统 Linux内核只有一个&#xff0c;发行版有很多种 内核来运行程序和管理像磁盘和打印机等硬件设备的核心程序 终端…

AD20中关于“Net(s) Not Found in Differential Pair”的解决方法

问题描述&#xff1a; Net(s) Not Found in Differential Pair&#xff1a;在差分对中找不到网络 我们需要在原理图设计中需要添加差分对&#xff0c;已经遵循了_N _P 结尾&#xff0c;也添加了差分对标识符&#xff0c;但是转换到PCB时显示差分对报错 解决方法&#xf…

GSA、GSEA、ssGSEA、GSVA用到的统计学知识点

文章目录 概率密度函数&#xff08;probability density function&#xff0c;PDF&#xff09;分布函数&#xff08;Cumulative Distribution Function&#xff0c;CDF&#xff09;核密度估计&#xff08;KDE&#xff09;经验累计分布函数&#xff08;Empirical Cumulative Dis…

VUE_nuxt启动只能通过localhost访问,ip访问不到:问题解决

修改项目根目录下的 package.json "config": {"nuxt": {"host": "0.0.0.0","port": "3000"} } 这样项目启动后就可以通过ip进行访问了

目标检测论文模型笔记——YOLO系列

1. YOLOv1的核心思想&#xff1a; YOLOv1&#xff1a;使用整张图作为输入&#xff0c;直接在输出层回归bounding box和类别&#xff1b;&#xff08;one-stage&#xff09;Faster RCNN&#xff1a;使用用整张图作为输入&#xff0c;但整体采用了RCNN&#xff1a; proposalclas…