当前位置: 首页 > news >正文

(动画版)排序算法 -希尔排序

文章目录

  • 1. 希尔排序(Shellsort)
    • 1.1 简介
    • 1.2 希尔排序的步骤
    • 1.3 希尔排序的C实现
    • 1.4 时间复杂度
    • 1.5 空间复杂度
    • 1.6 希尔排序动画

1. 希尔排序(Shellsort)

1.1 简介

希尔排序(Shell's Sort),又称缩小增量排序(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法,其核心思想是通过逐渐减小元素之间的间隔,使得序列在初始阶段就呈现局部有序,从而减少插入排序的工作量。希尔排序的基本思想是将待排序的序列划分成若干个子序列,分别进行插入排序。随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个序列恰被分成一组,此时再对全体记录进行一次直接插入排序,排序完成。

1.2 希尔排序的步骤

  1. 选择一个增量序列,该序列通常是递减的正整数序列。常用的增量序列有希尔建议的序列、Hibbard序列、Sedgewick序列等。增量序列的选择会直接影响希尔排序的性能。
  2. 使用选定的增量序列进行外层循环,每次循环缩小增量。
  3. 在每一轮外层循环中,通过增量对元素进行分组,每组包含相隔一定间隔的元素。这一步骤旨在逐步减小元素之间的间隔,从而实现序列的局部有序。
  4. 在每一组内,通过插入排序对元素进行排序。这是希尔排序的关键步骤,通过比较相隔增量的元素,并在需要时交换它们的位置,逐步实现每个小组的局部有序。
  5. 重复外层循环和内层循环,逐渐减小增量,直到增量为1。最后一次外层循环使用增量为1,相当于进行一次标准的插入排序。此时,整个序列已经基本有序,最终完成排序。

1.3 希尔排序的C实现


#include <stdio.h>// 希尔排序函数(带步骤输出)
void shellSort(int arr[], int n) {// 初始增量设置为数组长度的一半for (int gap = n / 2; gap > 0; gap /= 2) {printf("当前间隔 (gap): %d\n", gap); // 输出当前的间隔// 对每个增量子数组进行插入排序for (int i = gap; i < n; i++) {int temp = arr[i];int j;printf("  当前插入元素 (arr[%d]): %d\n", i, temp);// 在增量子数组中向前移动元素,直到找到合适的位置for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {printf("    比较并移动元素 (arr[%d] = %d) 到位置 arr[%d]\n", j - gap, arr[j - gap], j);arr[j] = arr[j - gap];}// 将当前元素放到合适的位置arr[j] = temp;printf("  将元素 %d 插入到位置 arr[%d]\n", temp, j);// 输出每次插入后的数组状态printf("  当前数组状态: ");for (int k = 0; k < n; k++) {printf("%d ", arr[k]);}printf("\n");}// 输出每次间隔完成后的数组状态printf("间隔 %d 排序后的数组: ", gap);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n\n");}
}// 打印数组函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}// 主函数
int main() {int arr[] = {22, 48, 65, 68, 68, 10, 84, 45, 37, 88, 71, 89, 89, 13, 59};int n = sizeof(arr) / sizeof(arr[0]);printf("排序前的数组: \n");printArray(arr, n);shellSort(arr, n);printf("排序后的数组: \n");printArray(arr, n);return 0;
}

希尔排序(Shell Sort)的时间复杂度和空间复杂度分析如下:

1.4 时间复杂度

希尔排序的时间复杂度取决于所选的增量序列。对于不同的增量序列,希尔排序的性能可能会有很大的差异。
  1. 最坏情况:使用原始的希尔增量(即每次将增量减半,从 n 2 \frac{n}{2} 2n开始),希尔排序的时间复杂度在最坏情况下可以达到O(n2)。这通常发生在数据已经接近有序但尚未完全有序的情况下,因为此时的插入排序(希尔排序在增量为1时的特殊情况)可能会执行大量的元素移动。

  2. 平均情况:在实际应用中,希尔排序通常比简单的插入排序要快得多,特别是在处理大数据集时。虽然其最坏情况时间复杂度较高,但平均情况下,希尔排序的性能通常优于O(n2)的排序算法。

  3. 最优增量序列:通过选择更好的增量序列(如Hibbard增量、Sedgewick增量等),可以进一步改进希尔排序的性能。然而,找到最优的增量序列仍然是一个未解决的问题,因此希尔排序的时间复杂度在很大程度上仍然是一个开放性问题。

  4. 实验观察:实验结果表明,对于中等规模的数据集,希尔排序的性能通常与快速排序(Quick Sort)相当,甚至在某些情况下可能更快。然而,对于非常大的数据集,快速排序通常具有更好的性能。

1.5 空间复杂度

希尔排序是一种原地排序算法(in-place sorting algorithm),这意味着它只需要一个与输入数组大小相同的额外空间来存储临时变量(在插入排序的每一步中用于保存要插入的元素)。因此,希尔排序的空间复杂度是O(1)。

1.6 希尔排序动画

在希尔排序的动画中,用三种颜色来帮助理解排序过程:
  1. 橙色:当前插入的元素,表示正在考虑插入排序的那个元素(i)。
  2. 绿色:正在比较或插入的位置,表示当前正在比较或准备插入的具体位置(j)。
  3. 紫色:属于同一间隔组的元素,用来表明在当前的间隔(gap)下,这些元素属于同一组,将通过插入排序在组内进行比较和排序。

shell

相关文章:

(动画版)排序算法 -希尔排序

文章目录 1. 希尔排序&#xff08;Shellsort&#xff09;1.1 简介1.2 希尔排序的步骤1.3 希尔排序的C实现1.4 时间复杂度1.5 空间复杂度1.6 希尔排序动画 1. 希尔排序&#xff08;Shellsort&#xff09; 1.1 简介 希尔排序&#xff08;Shells Sort&#xff09;&#xff0c;又…...

delphi fmx android 自动更新(二)

自己写了一个升级的类,支持android与windows 1,下载升级包,可以设置进度条 我这里用的fmxui的进度条,你也可以用原生的 http下载我用的nethttpclient, 进度条设置是比较方便的 首先获取下载文件的大小 用nethttpclient.head函数请求文件地址,得到contentlength 接着…...

蓝队知识浅谈(中)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;蓝队基础之网络七层杀伤链_哔哩哔哩_bilibili 本文主要分享一些蓝队相关的知识。 一、网络杀伤链 网络杀伤链&#xff08;Cyber Kill Chain&…...

解决vue3+ts打包项目时会生成map文件

在正常未配置的情况下使用npm run build 命令打包&#xff0c;会生成很多的js和map文件,map文件是为了方便我们在生产环境进行更友好的代码调试&#xff0c;但是这样就存一个安全问题&#xff1b;容易被攻击&#xff1b; 解决方法&#xff1a;在package.json文件&#xff0c;重…...

webpack指南

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;webpack篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南 概念 中文&#xff1a; webpack | webpack中文文档 | webpack中文网 英文&…...

关于QUERY_ALL_PACKAGES权限导致Google下架apk

谷歌商店被下架,原因是第三方使用了 QUERY_ALL_PACKAGES 权限&#xff1b; Google在高版本上限制了此权限的使用。当然&#xff0c;并不是 QUERY_ALL_PACKAGES 这个权限没有了&#xff0c;而是被列为敏感权限&#xff0c;必须有充分的理由说明&#xff0c;才允许上架 GP&#…...

优化时钟网络之时钟抖动

Note&#xff1a;文章内容以Xilinx 7系列FPGA进行讲解 1、什么是时钟抖动 时钟抖动就是时钟周期之间出现的偏差。比如一个时钟周期为10ns的时钟&#xff0c;理想情况下&#xff0c;其上升沿会出现在0ns&#xff0c;10ns&#xff0c;20ns时刻&#xff0c;假设某个上升沿出现的时…...

C++《继承》

在之前学习学习C类和对象时我们就初步了解到了C当中有三大特性&#xff0c;分别是封装、继承、多态&#xff0c;通过之前的学习我们已经了解了C的封装特性&#xff0c;那么接下来我们将继续学习另外的两大特性&#xff0c;在此将分为两个章节来分别讲解继承和多态。本篇就先来学…...

微澜:用 OceanBase 搭建基于知识图谱的实时资讯流的应用实践

本文作者&#xff1a; 北京深鉴智源科技有限公司架构师 郑荣凯 本文整理自北京深鉴智源科技有限公司架构师郑荣凯&#xff0c;在《深入浅出 OceanBase 第四期》的分享。 知识图谱是一项综合性的系统工程&#xff0c;需要在在各种应用场景中向用户展示经过分页的一度关系。 微…...

【LeetCode】【算法】538. 把二叉搜索树转换为累加树

LeetCode 538. 把二叉搜索树转换为累加树 题目 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下…...

YoloV8改进策略:注意力改进|EPSANet,卷积神经网络上的高效金字塔挤压注意力块|即插即用|代码+改进方法

摘要 论文介绍 本文介绍的论文是“EPSANet:卷积神经网络上的高效金字塔挤压注意力块”,该论文提出了一种新颖、轻量且有效的注意力方法,即金字塔挤压注意力(PSA)模块。论文通过替换ResNet瓶颈块中的 3 3 3 \times 3 3...

Nextflow最佳实践:如何在云上高效处理大规模数据集

1. Nextflow 软件架构介绍 Nextflow 是一个用于简化数据驱动计算流程的工具&#xff0c;可以在各种计算环境中轻松部署。它采用了分布式计算和容器技术&#xff0c;实现了高度模块化、可重复性和可扩展性。NextFlow 的软件架构主要包括以下几个部分&#xff1a; 用户界面&…...

数据结构:顺序表(动态顺序表)

专栏说明&#xff1a;本专栏用于数据结构复习&#xff0c;文章中出现的代码由C语言实现&#xff0c;在专栏中会涉及到部分OJ题目&#xff0c;如对你学习有所帮助&#xff0c;可以点赞鼓励一下博主喔&#x1f493; 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;数…...

springboot040社区医院信息平台

&#x1f345;点赞收藏关注 → 添加文档最下方联系方式领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 项目视频 spr…...

windows下QT5.12.11使用MSVC编译器编译mysql驱动并使用详解

1、下载mysql开发库,后面驱动编译的时候需要引用到,下载地址:mysql开发库下载 2、使用everything搜索:msvc-version.conf,用记事本打开,添加:QMAKE_MSC_VER=1909。不然msvc下的mysql源码加载不上。...

c++写一个死锁并且自己解锁

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…...

JavaScript方法修改 input type=file 样式

html中的<input type "file">的样式很难修改&#xff0c;又跟页面风格很不匹配。我就尝试了几种方法&#xff0c;但是不管是用label还是用opacity:0都很麻烦&#xff0c;还老是出问题&#xff0c;所以最后还是用JavaScript来解决。 下面附上代码&#xff1a;…...

群控系统服务端开发模式-应用开发-前端个人信息功能

个人信息功能我把他分为了3部分&#xff1a;第一部分是展示登录者信息&#xff1b;第二步就是登录者登录退出信息&#xff1b;第三部分就是修改个人资料。 一、展示登录者信息 1、优先添加固定路由 在根目录下src文件夹下route文件夹下index.js文件中&#xff0c;添加如下代码 …...

【jupyter】文件路径的更改

使用过 jupyter notebook 环境的同行&#xff0c; 都体会过随机生成 .html 静态网页的过程&#xff0c; 虽然文档较小&#xff0c; 但是不堪反复使用积少成多。本文基于windows系统。 找到 runtime 目录 一般 jupyter 默认 runtime 在下述格式目录中 C:\Users\用户名\AppData…...

Ruby编程语言全景解析:从基础到进阶

Ruby是一种动态的、面向对象的编程语言&#xff0c;以其优雅的语法和强大的功能而闻名于世。自从1995年由日本程序员松本行弘&#xff08;Yukihiro Matsumoto&#xff09;发布以来&#xff0c;Ruby便迅速成为了开发者中颇受欢迎的编程语言之一。无论是构建简单的脚本还是复杂的…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...