1 希尔排序

希尔排序(Shell Sort)是D.L.Shell于1959年提出来的一种排序算法,在这之前排序算法的时间复杂度基本都是O(n²),希尔排序算法是突破这个时间复杂度的第一批算法之一。

1.1 基本概念与原理

希尔排序通过将原始列表分割成若干子序列进行插入排序,随着增量逐渐减小,最终对整个列表进行一次插入排序。
核心思想
‌1.增量序列‌:选择一个增量序列(gap sequence),将数组分成若干子序列
‌2.子序列排序‌:对每个子序列进行插入排序
‌3.逐步缩小增量‌:重复上述过程,直到增量为1
‌4.最终排序‌:当增量为1时,对整个数组进行最后一次插入排序
希尔排序之所以高效,是因为它利用了插入排序在"部分有序"数组上表现良好的特性。通过前期的大增量排序,使得数组逐渐趋于有序,减少了后期小增量排序时的数据移动次数。

1.2 算法执行过程

1.增量序列选择
希尔排序的性能很大程度上取决于增量序列的选择。常见的增量序列有:
Shell原始序列:n/2, n/4, …, 1
Hibbard序列:1, 3, 7, …, 2^k - 1
Sedgewick序列:1, 5, 19, 41, 109,…
2. 具体执行步骤
以数组[8, 3, 9, 1, 5, 7, 2, 6]为例,使用Shell原始序列(n/2, n/4,…):
‌初始数组‌:[8, 3, 9, 1, 5, 7, 2, 6] (n=8)
‌第一轮(gap=4,分成4组序列)‌
子序列1:[8,5] → [5,8]
子序列2:[3,7] → [3,7]
子序列3:[9,2] → [2,9]
子序列4:[1,6] → [1,6]
‌结果‌:[5, 3, 2, 1, 8, 7, 9, 6]
‌第二轮(gap=2,分成2组序列)‌
子序列1:[5,2,8,9] → [2,5,8,9]
子序列2:[3,1,7,6] → [1,3,6,7]
‌结果‌:[2, 1, 5, 3, 8, 6, 9, 7]
‌第三轮(gap=1,分成1组序列)‌
对整个数组进行插入排序
‌最终结果‌:[1, 2, 3, 5, 6, 7, 8, 9]

1.3 算法复杂度分析

时间复杂度
希尔排序的时间复杂度分析较为复杂,因为它依赖于增量序列的选择:
‌最坏情况‌:O(n²) - 当增量序列不佳时
‌平均情况‌
Shell原始序列:O(n^(3/2))
Hibbard序列:O(n^(3/2))
Sedgewick序列:O(n^(4/3))
‌最好情况‌:O(nlogn) - 当数组已经部分有序时
空间复杂度
希尔排序是原地排序算法,空间复杂度为O(1)。
稳定性
希尔排序是不稳定的排序算法,因为相同的元素可能在各自的插入排序中移动。

1.4 C语言实现希尔排序

#include <stdio.h>#define SORT_DATA_TYPE int/*** @brief 打印数据** @param arr 数组* @param n 数组元素个数*/
void print_array(int arr[], int n)
{int i;for (i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}/*** @brief 希尔排序** @param arr 待排序的数组* @param n 数组元素个数*/
void shell_sort(int arr[], int n)
{SORT_DATA_TYPE temp;int gap;int i, j;/* 初始增量gap为数组长度的一半,逐步缩小 */for (gap = n / 2; gap > 0; gap /= 2){/* 从第gap个元素开始,逐个对其所在子序列进行插入排序 */for (i = gap; i < n; i++){temp = arr[i];/* 对子序列进行插入排序 */for (j = i; j >= gap; j -= gap){if (arr[j - gap] > temp){arr[j] = arr[j - gap];}else{break;}}arr[j] = temp;print_array(arr, n); /* 查看每次排序结构,调试使用 */}printf("result :"); /* 查看每次排序结构,调试使用 */print_array(arr, n);}
}int main()
{SORT_DATA_TYPE arr[] = {4, 3, 2, 1};int n = sizeof(arr) / sizeof(arr[0]);printf("old arr : ");print_array(arr, n);shell_sort(arr, n);printf("new arr : ");print_array(arr, n);return 0;
}


不同类型的数组直接将SORT_DATA_TYPE全部替换为需要的类型,然后删除多余的宏定义即可支持任意类型数组的希尔排序。

1.5 简单测试

通过使用数组[4,3,2,1]演示希尔排序的执行过程:
在这里插入图片描述
可以使用如下图片演示这一过程:
在这里插入图片描述

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

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

相关文章

网络协议——HTTPS协议

目录 一、HTTPS是什么 加密是什么 二、HTTPS的工作过程 &#xff08;一&#xff09;对称加密 &#xff08;二&#xff09;非对称加密 &#xff08;三&#xff09;在非对称加密的基础上&#xff0c;引入证书校验 证书是什么 证书的内容 用证书解决中间人攻击 三、总结 …

React 基础实战:从组件到案例全解析

React 基础实战专栏:从组件到案例全解析 本专栏围绕 React 核心概念(组件、Props、State、生命周期)展开,通过 6个实战案例+核心知识点拆解,帮你掌握 React 基础开发逻辑,每篇聚焦1个实战场景,搭配完整代码与原理讲解,适合 React 入门者巩固基础。 专栏目录 【组件传…

ARM芯片架构之CoreSight Channel Interface 介绍

CoreSight Channel Interface&#xff08;通道接口&#xff09;详解1. 概述 Channel Interface 是 ARM CoreSight 架构中用于在不同组件之间传递触发事件的专用接口。它是 Event Interface 的增强版本&#xff0c;支持多通道、双向通信&#xff0c;以及同步与异步两种时钟域连接…

Blender模拟结构光3D Scanner(二)投影仪内参数匹配

关于投影仪外参的设置可参见前一篇文章 Blender模拟结构光3D Scanner&#xff08;一&#xff09;外参数匹配-CSDN博客 使用Projectors插件模拟投影仪 Step 1 在Github下载插件&#xff08;https://github.com/Ocupe/Projectors&#xff09;。下载zip压缩包即可&#xff0c;无…

synchronized的作用

目录 一、核心作用 二、实现原理&#xff1a;基于"对象锁" 三、使用方式 四、锁的优化 五、优缺点 六、总结 synchronized 是 Java 中用于解决多线程并发安全问题的核心关键字&#xff0c;它的主要作用是实现线程间的同步&#xff0c;确保多个线程在访问共享资…

机试备考笔记 14/31

2025年8月14日 小结&#xff1a;&#xff08;17号整理14号的笔记&#xff0c;这辈子真是有了w(&#xff9f;Д&#xff9f;)w&#xff09;昨天摔了跤大的&#xff0c;今天好妈妈在家&#xff0c;松弛。省流&#xff1a;6道中等&#xff0c;明天只学了10分钟嘻嘻 目录LeetCode22…

dolphinscheduler中任务输出变量的问题出现ArrayIndexOutOfBoundsException

一段脚本任务如下&#xff1a;ret/data/dolphinscheduler/loadOraTable.sh "yonbip/yonbip10.16.10.69:1521/orcl" "select t.bondcontractno,t.olcunissuemny from yonbip.bond_contract t " "/dmp/biz" "bip" "2025-08-13"…

OpenCv(二)——边界填充、阈值处理

目录 一、边界填充&#xff08;Border Padding&#xff09; 1. 常见填充类型及效果 2.代码示例 &#xff08;1&#xff09;constant边界填充&#xff0c;填充指定宽度的像素 &#xff08;2&#xff09;REFLECT镜像边界填充 &#xff08;3&#xff09;REFLECT_101镜像边界…

Leetcode 15 java

今天复习一下翻转二叉树 226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2…

嵌入式学习的第四十九天-时钟+EPIT+GPT定时器

一、时钟1.时钟系统基本概念&#xff08;1&#xff09;PLL (锁相环, Phase-Locked Loop)作用&#xff1a;PLL是一种反馈控制电路&#xff0c;用于生成稳定的高频时钟信号。它通过将输出时钟与参考时钟进行比较和调整&#xff0c;可以产生比输入参考时钟频率高得多的输出时钟。倍…

Python Sqlalchemy数据库连接

Python Sqlalchemy数据库连接一、连接数据二、模型三、ORM操作一、连接数据 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker# 1. 连接数据库 dbHost postgres://用户名:密码主机:端口/数据库名 engine create_engine(dbHost) # create_engi…

【Node.js】ECMAScript标准 以及 npm安装

目录 一、 ECMAScript标准 - 默认导出和导入 二、ECMAScript标准 - 命名导出和导入 三、包的概念 五、 npm - 安装所有依赖 六、 npm - 全局软件包 Node.js总结 总结不易~ 本章节对我有很大的收获&#xff0c; 希望对你也是&#xff01;&#xff01;&#xff01; 本节素材…

NPM 、 NPX

NPM vs. NPX 简单来说&#xff0c;npm 是一个 node 包管理器&#xff0c;npx 是一个 Node 包执行器。 NPX 是一个 Node 包执行器&#xff0c;该 Node 包可以是本地也可以是远程的。允许开发者在无需安装的情况下执行任意 Node 包。npm 在安装nodejs 就自动带了 npm install -g …

守护品质安全,防伪溯源系统打造全链路信任体系

一、引言在当下这个信息透明、品质至上的时代&#xff0c;防伪溯源已经成为众多品牌保护自身利益、提升消费者信任度的重要手段。为了满足市场上对高效、可靠的防伪溯源查询系统的迫切需求&#xff0c;榕壹云精心打造了一款防伪溯源查询系统。二、项目背景随着商品市场的不断扩…

【完整源码+数据集+部署教程】无人机航拍视角洪水检测与受灾房屋识别图像分割救援指导系统源码和数据集:改进yolo11-DCNV2

背景意义 研究背景与意义 随着全球气候变化的加剧&#xff0c;极端天气事件的频率和强度不断上升&#xff0c;洪水作为一种常见的自然灾害&#xff0c;给人类社会带来了严重的威胁。洪水不仅导致人员伤亡和财产损失&#xff0c;还对基础设施和生态环境造成了深远的影响。因此&a…

C# 结构体与类的区别是什么?

结构体是值类型是储存在栈中独立储存的,数据与数据之间不会相互影响,即使将一个结构体赋值给另外一个结构体也不会相互影响。 类是一个模板,实例出来的对象是独立的不会相互影响,但是将一个对象赋值给另一个对象时 会把指向堆内存中数据的指针赋值给另一个对象.从而发生两个变量…

Redis GEO

Redis GEO 引言 Redis 是一款高性能的键值存储系统,广泛应用于缓存、消息队列等领域。Redis GEO 是 Redis 2.4 版本后新增的一个功能,用于存储地理位置信息。本文将详细介绍 Redis GEO 的概念、使用方法以及应用场景。 什么是 Redis GEO? Redis GEO 是 Redis 的一个模块…

Go从入门到精通系列学习路线规划

Go从入门到精通系列学习路线规划 目录导航 Go从入门到精通系列学习路线规划首页说明 第1篇_Go语言初探_环境搭建与HelloWorld 第2篇_Go语言基础语法_变量常量与数据类型 第3篇_Go语言控制结构_条件判断与循环 第4篇_Go语言函数详解 第5篇_Go语言数据结构详解 第6篇_Go语言结构体…

Grid系统概述

目录 概念及功能 网格对象&#xff08;Grid Object&#xff09; 和世界对象&#xff08;World Object&#xff09; 工作流程 概念及功能 TrinityCore 的 Grid 系统是一套复杂的地图分区管理机制&#xff0c;其核心目标是通过动态管控游戏世界的区域状态和对象生命周期&#…

一文搞懂LLM大模型!LLM从入门到精通万字长文(2024.12月最新)

LLM从入门到精通精品文章 目录 一、LLM基本概念 二、LLM发展历程 三、LLM大模型的分类 四、LLM主流大模型类别 五、LLM大模型建立的流程 六、Fine-Tuning 七、Prompt-Tuning 八、超大规模参数模型Prompt-Tuning方法 8.1上下文学习 In-Context Learning 8.2.指令学习 …