详解十大经典排序算法(四):希尔排序(Shell Sort)

排序算法——希尔排序 Shell Sort(C++ Java) 希尔排序(ShellSort)也称递减增量排序算法,其实它是插入排序的优化版本。希尔排序是非稳定排序算法。 希尔排序对插入排序的以下两点进行改进: (1)插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率; (2)一般来说插入排序是低效的,因为插入排序每次只能将数据移动一位。 原始的算法实现在最坏的情况下需要进行O(n^2)的比较和交换。V. Pratt的书对算法进行了少量修改,可以使得性能提升至O(n(logn)^2)。这比最好的比较算法的O(nlogn)要差一些。 希.. 阅读详情

算法原理

希尔排序是一种基于插入排序的排序算法,也被称为缩小增量排序。它通过将待排序的序列分割成若干个子序列,对每个子序列进行插入排序,然后逐步缩小增量,最终使整个序列有序。

算法描述

希尔排序(Shell Sort)是一种基于插入排序的算法,由Donald Shell于1959年提出。它是插入排序的一种更高效的改进版本。希尔排序的核心思想是将原始数据分成多个子序列,先对每个子序列进行插入排序,然后逐步减少子序列的数量,最终对整个数据序列进行插入排序。

这个算法的关键特点是其间隔序列的选择,即每次排序时元素之间的间隔。开始时,间隔较大,随着算法的进行,间隔逐渐减小,最后间隔为1,即普通的插入排序。通过这种方式,希尔排序可以快速减少大量的初期乱序,从而提高排序效率。

希尔排序的步骤如下:

  1. 选择合适的间隔序列:最初的版本使用序列长度的一半作为第一个间隔,然后逐步减半,直到间隔为1。现代版本可能会使用不同的间隔序列。

  2. 分组并排序:按照当前间隔将数组分为多个子序列,独立地对每个子序列应用插入排序。

  3. 减少间隔并重复:减少间隔大小,重复上述过程,直到间隔减至1。

  4. 最终排序:当间隔减至1时,进行一次标准的插入排序,此时由于序列已经部分排序,这一步骤会非常快。

动画演示

在这里插入图片描述

代码实现

public static void shellSort(int arr[]) {
        int n = arr.length;

        //设置排序的间隔(gap)。
        //初始间隔设置为数组长度的一半,每次循环后间隔减半。
        //循环继续直到间隔减至0。
        for (int gap = n / 2; gap > 0; gap /= 2) {

            //内层循环从gap开始,对数组进行遍历。
            for (int i = gap; i < n; i += 1) {
                int temp = arr[i];//存储当前元素的值。
                int j;//用于后续的内嵌循环,用于比较和交换元素。

                //此循环用于将较大的元素向右移动。
                //当j大于等于gap且arr[j - gap](当前元素的前一个间隔位置的元素)大于temp(当前元素)时,将arr[j - gap]向右移动到arr[j]的位置。
                for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                    arr[j] = arr[j - gap];
                }
                //此处的j 是上面循环 j -= gap 后的。
                arr[j] = temp;
            }
        }


    }

算法复杂度

时间复杂度(最坏)时间复杂度(最好)时间复杂度(平均)空间复杂度稳定性
O(n^2)O(nlogn)O(n^1.5)O(1)不稳定
  • 最好情况:O(nlogn)
  • 平均情况:取决于间隔序列。对于原始的间隔序列(减半序列),平均时间复杂度为O(n^1.5)。
  • 最坏情况:取决于间隔序列。对于某些不佳的间隔序列,最坏情况可以达到O(n^2)。
  • 空间复杂度:O(1)。希尔排序是一种原地排序算法。

希尔排序的优化方式

<<<前方高能 量力而行>>>

希尔排序的性能在很大程度上依赖于间隔序列的选择。不同的间隔序列会导致算法的性能有显著差异。优化希尔排序通常涉及使用更有效的间隔序列,而不是初始版本中的简单递减序列(如数组长度的一半递减至1)。以下是几种常见的优化方法:

  1. 优化间隔序列
  • Hibbard序列:使用形式为 2^k - 1 的间隔,如 1, 3, 7, 15, 31, … 这样的序列可以使希尔排序达到大约 O(n^(3/2)) 的时间复杂度。

  • Sedgewick序列:这是一种更复杂的间隔序列,可以进一步优化性能。一个常见的Sedgewick序列是 1, 5, 19, 41, 109, …

  • Knuth序列:使用形式为 (3^k - 1) / 2 的间隔,如 1, 4, 13, 40, 121, …

这些序列都是试图在排序过程中更有效地打乱数组,从而避免某些特定情况下的糟糕性能。

  1. 动态间隔

一种更高级的优化是根据数组的特定特征动态选择间隔。这种方法通常适用于特定类型的数据或在需要极致优化时使用。

下面是一个使用Hibbard间隔序列的希尔排序的Java实现示例:

 public static void sort(int[] arr) {
        int n = arr.length;
        int h = 1;

        // 计算最大间隔
        while ((h * 2) - 1 < n) {
            h = h * 2;
        }
        h = h - 1;

        // 希尔排序
        while (h >= 1) {
            for (int i = h; i < n; i++) {
                int temp = arr[i];
                int j;
                for (j = i; j >= h && arr[j - h] > temp; j -= h) {
                    arr[j] = arr[j - h];
                }
                arr[j] = temp;
            }
            h = (h + 1) / 2 - 1; // 更新间隔为下一个较小的Hibbard数
        }
    }

这段代码首先计算最大的Hibbard间隔,然后在每次迭代中减小间隔,直到间隔为1。每个间隔都会对数组进行一轮希尔排序。这种使用Hibbard间隔的方法通常比简单的递减间隔方法表现得更好。


相关概念
• 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
• 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
• 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
• 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

十大经典排序算法简介 本文对十大经典排序算法做简要的总结(按常用分类方式排列),包含核心思想、时间/空间复杂度及特点。1)稳定:归并、冒泡、插入、计数、桶、基数。2)非比较排序(计数/桶/基数)空间换时间。4)稳定需求:归并排序(大数据)或基数排序(整数)时间:O(n \times k)(k为最大位数)时间:O(n\log n)(最坏O(n^2))8. 计数排序 (COUNTING SORT)时间:O(n^{1.3})(依赖增量序列)2)不稳定:选择、希尔、快速、堆。1)归并排序需要额外O(n)空间。 阅读详情

相关推荐

玄机-Linux权限维持-后门

玄机-Linux权限维持-后门

m0_46439803的博客 763

排序算法研究之希尔排序(shell sort)

前面几个小节,我们分别介绍了冒泡排序,插入排序,快速排序 选择排序本节,我们介绍插入排序的改进版的希尔排序。 希尔排序是1959年,Shell发明的,这是第一个突破O(n2)的排序算法,他与直接插入排序不同的是,他会优先比较距离较近的元素。因此,希尔排序又叫做缩小增量排序。 1、算法思想 首先,将待排序的序表分割成若干个形如L[i,i+d,i+2d,…… i+kd]的“特殊”子表,然后分别的进行直...

爱喝舒化奶的博客 2万+

基于价值的深度强化学习:DQN

本文主要是介绍DQN原理和算法伪代码和代码实现,算法实现包括pytorch版本和stable-baselines3版本

溯源的专栏 1082

希尔排序详解(Shell Sort)

直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

Wzill 1万+

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 273

国产大模型高考横评:数学推理与教育落地能力实测

大模型能力评估正从开放榜单转向封闭任务的确定性验证,高考作为强逻辑、低容错、高精度的标准化考试,成为检验模型真实推理能力的理想标尺。其核心在于考察知识覆盖、步骤完整性、单位敏感性与教学对齐度,而非单纯答案正确率。数学解答题尤其凸显模型在前提校验、条件枚举与过程可控性上的差异,反映出训练数据与教育语料深度耦合带来的工程化优势。该范式已延伸至语文语感建模、英语表达习惯适配及理综跨学科缝合等场景,为智能阅卷、精准答疑和教培系统集成提供可复现、可解释、可部署的技术依据。

weixin_30436581的博客 287

十大经典排序算法——希尔排序(Shell Sort)

文章目录算法代码 算法 (1)希尔排序这个名字,来源于它的发明者希尔,也称作“缩小增量排序”,是插入排序的一种更高效的改进版本。 (2)插入排序对于小规模数据数据或者基本有序或者时十分高效。其大规模的乱序数组的时候效率是比较慢的,因为它每次只能将数据移动一位。 (3)希尔排序为了加快插入的速度,让数据移动的时候可以实现跳跃移动,节省了一部分的时间开支。 基本思想: 首先它把较大的数据集合分割成若...

Heorin X的博客 317

使用 VPN 访问太理内部网相关问题总结【太原理工大学】

电脑连接 VPN,访问校园内部网相关问题总结,太原理工大学。

m0_52861684的博客 9873

DSA之十大排序算法第四种:Shell Sort

希尔排序 正如我们上一节讨论的直接插入排序而言: 直接插入排序类似于 班级学生身高从低到高进行站队:第一个学生先进行站队,第二个学生若是比他低,则站前面否则站后面。无论如何,此时他们二人已经有序,此刻第三个学生来了,同理 找到自己的位置 插进站队里面。一直到最后一名学生也找到自己的位置,整个排队过程结束。 但是这样的直接插入排序存在如下问题: 直接插入排序对于基本上有序的数列,尤其是当然最好的情...

孤傲小二~阿沐的博客 6271

【OpenClaw从入门到精通】零基础入门——OpenClaw核心概念快速理解(2026入门版)

OpenClaw是一个强大的AI代理框架,旨在构建智能化的自动化任务处理系统。随着人工智能技术的快速发展,OpenClaw为开发者和企业提供了一个完整的解决方案,用于创建能够理解、学习和执行复杂任务的智能体。本文将带领零基础的读者快速理解OpenClaw的核心概念,从基础架构到实际应用,为后续深入学习奠定坚实基础。通过本文的学习,你将掌握OpenClaw的基本原理、核心组件和快速上手方法。

一键难忘的博客 324

【数据湖仓】:Iceberg、Hudi 和 Paimon 对比

适用于需要多计算引擎支持和复杂查询的离线批处理场景。其中立性和灵活性使其成为构建新型数据平台的理想选择。:在需要高频数据更新和高效小文件管理的场景中表现出色,适合实时数据处理和增量数据更新的业务需求。:专为实时流式数据处理设计,适用于对数据实时性要求高的业务场景,如实时数据分析和实时指标监控。通过以上分析,可以看出 Apache Iceberg、Apache Hudi 和 Apache Paimon 各有其独特的优势和适用场景。企业应根据自身业务需求和技术栈选择合适的数据湖仓方案,以充分发挥其价值。

欢迎来到我的博客,一起探索代码里的世界! 1607

排序算法-希尔排序(Shell Sort)

文章目录希尔排序法介绍希尔排序法算法时间复杂度其他排序法的比较 希尔排序法介绍 希尔排序法(Shell Sort)是D.L.Shell于1959年提出的一种排序算法,在这之前的排序算法如冒泡排序、简单选择排序、直接插入排序等算法的的时间复杂度都为O(n2)O(n^{2})O(n2),而希尔排序突破了这一时间复杂度。 【原理】 直接插入排序算法比冒泡排序和简单选择排序性能都要高,尤其在序列基本有序并...

白杨 2641

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

排序算法(4)希尔排序(Shell Sort)

插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 4、希尔排序(Shell Sort) 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 4.1 算法描述 先将整...

cowbin2012的专栏 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

十大经典排序算法之希尔排序(Shell Sort)

希尔排序(Shell Sort) 1959年由唐纳德·希尔(Donald Shell)提出 希尔排序把序列看作是一个矩阵,分成 ???? 列,逐列进行排序 从某个整数逐渐减为1 当 ???? 为1时,整个序列将完全有序 因此,希尔排序也被称为递减增量排序(Diminishing Increment Sort) 矩阵的列数取决于步长序列(step sequence) ✓ 比如,如果步长序列为{1,5,19,41,109,…},就代表依次分成109列、41列、19列、5列、1列进行排序 ✓ 不同的步长序列,执

派拉斯兔子的博客 511

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

希尔排序(Shell Sort)

插入排序(InsertionSort),一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。...

happen_sea_roc的博客 2504

排序算法之四 希尔排序(Shell Sort)

概述 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 希尔排序中包含了分而治之的思想,首先将一个输入序列根据增量分成若干个子序列,然后对每个子序列分别进...

Markus 566

希尔排序时间复杂度_排序算法(五):Shell Sort 希尔排序

基本排序算法中的插入排序虽然逻辑较为简单,但当排序规模较大时,经常需要将元素一位一位地从一端移动到另一端,效率非常低。于是Donald Shell设计了一种基于插入排序的改进版排序算法,故被命名为 Shell Sort 希尔排序算法思想插入排序效率低下是因为其移动元素每次只能移动一位,当排序元素的规模较大时,需要将元素一位一位地从一端移动到另一端。而如果我们能够让元素一次性地移动到较远的...

weixin_39883260的博客 4994

经典算法之希尔排序(Shell Sort)

希尔排序时插入排序的一种,也称缩小增量排序,是直接插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

阿莫夕林的博客 953

希尔排序(Shell Sort)-- 高级排序算法

1 希尔排序(Shell Sort) 1959年Shell发明,第一个突破O(n2)O(n^2)O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 算法描述 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述: 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1; 按增量序列个数k,对序列进行k 趟排序; 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子

OuDiShenmiss的博客 330

排序---希尔排序(Shell Sort)

希尔排序是一种高效的排序算法,由唐纳德·希尔于1959年提出,通过分组插入排序和逐步缩小增量来优化插入排序的性能。其核心思想是将数组按增量分组并排序,最终完成整体排序。增量序列的选择直接影响效率,常见的有希尔原始增量、Knuth增量等。希尔排序时间复杂度取决于增量序列,空间复杂度为O(1),适用于中等规模数据排序和资源受限环境。尽管对大规模数据效率不如高级排序算法,其实用性和简单实现使其成为常用排序方案之一。

MzKyle的博客 2320

经典排序算法:希尔排序(Shell Sort)

希尔排序 希尔排序是Shell在1959年提出的一种排序算法,它出现的重要意义在于,之前的排序算法基本都是O(n²),希尔算法是突破这个时间复杂度的第一批算法之一,所以它绝对值得我们了解掌握! 希尔排序的基本思想是: 把记录按increment(增量)分组,对每组记录采用直接插入排序方法进行排序。 随着增量逐渐减小,所分成的组包含的记录越来越多,当增量的值减小到 1 时,整个数据合成为一组,构成一...

weixin_43060102的博客 221

python实现·十大排序算法之希尔排序(Shell Sort)

文章目录简介算法实现步骤Python 代码实现动画演示算法分析联系我们 简介 希尔排序(Shell Sort)属于插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。其基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下,效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高。

南风以南 406

Python排序算法(五)——希尔排序(Shell’s Sort)

有趣的事,Python永远不会 如需转发,请注明出处:小婷儿的pythonhttps://www.cnblogs.com/xxtalhr/p/10793487.html 一、希尔排序(Shell’s Sort)   希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直...

小麦粒的Python 1068

js 实现排序算法 -- 希尔排序(Shell Sort)

原文:   十大经典排序算法(动图演示) 希尔排序   1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 算法描述:   将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述: 选择一个增量序列t1,t2,…,tk,其中t1...

385

希尔排序(Shell Sort)

希尔排序(Shell Sort) 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 1 算法描述 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述: 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1; 按增量序列个数k,对序列进行k 趟排序; 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增

qq_47272824的博客 1520
上一篇: 详解十大经典排序算法(三):插入排序(Insertion Sort)
下一篇: 详解十大经典排序算法(五):归并排序(Merge Sort)
_蓝橙
博客等级 码龄7年 1179粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值