数据结构从入门到精通——希尔排序

希尔排序

  • 前言
  • 一、希尔排序( 缩小增量排序 )
  • 二、希尔排序的特性总结
  • 三、希尔排序动画演示
  • 四、希尔排序具体代码实现
    • test.c


前言

希尔排序是一种基于插入排序的算法,通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。这种算法交换操作结合了直接插入排序和分组交换的思想,交换操作和移动操作相结合,相比于直接插入排序,希尔排序交换操作和移动操作相结合,效率更高。希尔排序是非稳定排序算法。


一、希尔排序( 缩小增量排序 )

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列(由相隔某个“增量”的记录组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

在这里插入图片描述

二、希尔排序的特性总结

  1. 希尔排序是对直接插入排序的优化。
  2. gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在不同的书中给出的希尔排序的时间复杂度都不固定:

《数据结构(C语言版)》— 严蔚敏

在这里插入图片描述

《数据结构-用面相对象方法与C++描述》— 殷人昆

在这里插入图片描述
因为我们的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照: O(n1.25)到O(1.6*n1.25) 来算

  1. 稳定性:不稳定

希尔排序的特性总结起来主要有三点:交换性、移动性和跳跃性。这些特性使得希尔排序在处理大量数据时,相较于直接插入排序,效率有了显著的提升。

希尔排序的交换性体现在算法过程中,元素之间的比较和交换是基于它们之间的相对大小,而不是它们的物理位置。这一点与直接插入排序相似,但是希尔排序通过引入一个增量因子,使得交换操作可以在更大的范围内进行,从而减少了不必要的比较和移动。

移动性是指希尔排序在每一次迭代过程中,都会将待排序序列中的一部分元素移动到它们最终的位置。这个过程是通过增量因子的逐渐减小来实现的,每次迭代都会使得更多的元素达到它们正确的位置。这种特性使得希尔排序在处理大规模数据时,相较于直接插入排序,具有更好的时间和空间效率。

希尔排序的跳跃性是其最显著的特性之一。由于增量因子的存在,元素之间的比较和交换可以在不同的子序列之间进行,从而实现了跳跃式的移动。这种跳跃式的移动使得算法在初期就能够对元素进行较大范围的调整,从而快速接近有序状态。随着增量因子的逐渐减小,跳跃性逐渐减弱,算法逐渐过渡到局部调整阶段,直至最终完成排序。

综上所述,希尔排序的特性使得它在处理大量数据时具有较高的效率。通过交换性、移动性和跳跃性的结合,希尔排序在保持算法简单易懂的同时,实现了比直接插入排序更优的性能。这使得希尔排序在实际应用中具有广泛的应用价值,特别是在处理大规模数据集时,能够有效地提高排序效率。

三、希尔排序动画演示

希尔排序

希尔排序是一种基于插入排序的算法,通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。动画演示可以直观地展示希尔排序的每一趟排序过程,包括元素的移动和位置变化,帮助人们更好地理解和掌握希尔排序的原理和实现方法。

四、希尔排序具体代码实现

test.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){gap /= 2;//gap = gap/3 + 1;for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}}void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");
}
void TestOP()
{srand((unsigned int)time(0));const int N = 100000;int* a = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; i++){a[i] = rand();}int begin1 = clock();ShellSort(a, N);int end1 = clock();printf("ShellSort:%d\n", end1 - begin1);free(a);
}
void TestShellSort()
{int a[] = { 5, 3, 9, 6, 2, 4, 7, 1, 8 };PrintArray(a, sizeof(a) / sizeof(int));ShellSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}
int main()
{TestShellSort();TestOP();return 0;
}

这段代码实现的是希尔排序(Shell Sort)算法,这是一种基于插入排序的算法,通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。

下面是这段代码的详细解释:

  1. 函数定义:
void ShellSort(int* a, int n)

这个函数接受一个整数数组 a 和一个整数 n 作为参数,其中 n 是数组 a 的长度。

  1. 初始化间隔:
int gap = n;

这里初始化间隔 gap 为数组的长度 n。希尔排序的关键是选择合适的间隔序列。这个例子中选择了每次除以2的间隔,但也可以尝试其他的间隔序列,比如除以3再加1(被注释掉的那行)。

  1. 主循环:
while (gap > 1)

只要间隔 gap 大于1,就继续排序。

  1. 更新间隔:
gap /= 2;

每次循环后,间隔 gap 都除以2,这意味着每次迭代时,比较的元素之间的距离都会减半。

  1. 插入排序变种:
    内部的两个嵌套循环实现了一个插入排序的变种。外部循环遍历数组,而内部循环则负责将当前元素(加上间隔 gap)插入到已排序的序列中。
  • int end = i;:初始化 end 为当前外部循环的索引 i
  • int tmp = a[end + gap];:保存当前要插入的元素。
  • while (end >= 0):这个循环用于将 tmp 插入到正确的位置。如果 tmp 小于 a[end],则将 a[end] 向右移动 gap 个位置,并继续向前比较。如果 tmp 大于或等于 a[end],则停止循环。
  • a[end + gap] = tmp;:将 tmp 插入到正确的位置。
  1. 结束:
    gap 减少到1时,内部循环实际上就变成了标准的插入排序,因为每次只比较相邻的元素。

总的来说,希尔排序是插入排序的一个改进版本,通过允许非相邻元素的交换,它可以更快地移动数据。但需要注意的是,选择合适的间隔序列对于希尔排序的性能至关重要。

在这里插入图片描述


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

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

相关文章

【前端】Web API

1.Web API 简介 JS分为三大部分&#xff1a; ESCMScript&#xff1a;基础语法部分DOM API&#xff1a;操作页面结构BOM API&#xff1a;操作浏览器 Web API包含 DOM BOM 2.DOM基本概念 DOM全称 Document Object Mod…

最短路算法

数据结构、算法总述&#xff1a;数据结构/算法 C/C-CSDN博客 目录 朴素dijkstra算法 堆优化版dijkstra算法 Bellman-Ford算法 spfa 算法&#xff08;队列优化的Bellman-Ford算法&#xff09; spfa判断图中是否存在负环 floyd算法 朴素dijkstra算法 思路&#xff1a; 集合…

React简介

React简介 开发网页&#xff1a;引入react和react-native库。 开发手机端应用&#xff1a;引入react和react-dom库。 特点&#xff1a; 虚拟Dom&#xff08;开发者》react》虚拟Dom》Dom&#xff09;&#xff1b; 声明式&#xff08;结果为导向的编程&#xff0c;自动生成代码…

Linux相关命令(2)

1、W &#xff1a;主要是查看当前登录的用户 在上面这个截图里面呢&#xff0c; 第一列 user &#xff0c;代表登录的用户&#xff0c; 第二列&#xff0c; tty 代表用户登录的终端号&#xff0c;因为在 linux 中并不是只有一个终端的&#xff0c; pts/2 代表是图形界面的第…

长三角科技盛会“2024南京国际人工智能,机器人,自动驾驶展览会”

2024南京国际人工智能,机器人,自动驾驶展览会 2024 Nanjing International Ai, Robotics, Autonomous Driving Expo 时间:2024年11月22-24日 地点:南京国际博览中心 南京&#xff0c;这座历史悠久的文化名城&#xff0c;如今正站在新一轮科技产业变革的前沿&#xff0c;以人工…

uni app 空挡接龙

pc游戏 空挡接龙 还不完整。现在没时间搞了记录在这里&#xff0c;等以后有时间了再继续搞。 <template><view class"page_main"><view class"contentone"><canvas class"canvas_cla" style"z-index: 1;" canva…

【C++】每日一题 452 用最少数量的箭引爆气球

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一…

院子摄像头的监控

院子摄像头的监控和禁止区域入侵检测相比&#xff0c;多了2个功能&#xff1a;1&#xff09;如果检测到有人入侵&#xff0c;则把截图保存起来&#xff0c;2&#xff09;如果检测到有人入侵&#xff0c;则向数据库插入一条事件数据。 打开checkingfence.py&#xff0c;添加如下…

嵌入式学习-ARM-Day4

嵌入式学习-ARM-Day4 实现三个LED灯亮灭 .text .global _start _start: 使能GPIOE的外设时钟 RCC_MP_AHB4ENSETR的第[4]设置为1即可使能GPIOE时钟 LED1 LDR R0,0X50000A28 指定寄存器地址 LDR R1,[R0] 将寄存器原来的数值读取出来&#xff0c;保存到R1中 ORR R1,R1,#(0x…

Springboot笔记-03

1.properties配置文件 #配制oerson的值 person.lastname张三 person.age12 person.birth2017/12/12 person.bossfalse person.dog.namedag person.dog.age15 person.maps.k1v1 person.maps.k212 person.listsa,b,c运行结果乱码 因为idea默认是utf-8编码而properties是ascall编…

Bytebase 2.14.1 - 分支 (Branching) 功能支持 Oracle

&#x1f680; 新功能 分支 (Branching) 功能支持 Oracle。为 SQL 编辑器添加了项目选择器。 新增 SQL 审核规范&#xff1a; 禁止混合 DDL、DML 语句。禁止对同一张表进行不同类型的 DML 变更 (UPDATE,INSERT,DELETE)。 &#x1f514; 重大变更 工作空间设置中的「数据访问…

大屏可视化综合展示解决方案

1.系统概述 1.1.需求分析 1.2.重难点分析 1.3.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 2.3.接口及要求 3.系统功能设计 3.1.功能清单列表 3.2.数据源管理 3.3.数据集管理 3.4.视图管理 3.5.仪表盘管理 3.6.移动端设计 3.1.系统权限设计 3.…

利用Scala与Apache HttpClient实现网络音频流的抓取

概述 在当今数字化时代&#xff0c;网络数据的抓取和处理已成为许多应用程序和服务的重要组成部分。本文将介绍如何利用Scala编程语言结合Apache HttpClient工具库实现网络音频流的抓取。通过本文&#xff0c;读者将学习如何利用强大的Scala语言和Apache HttpClient库来抓取网…

c++基础学习第六天(多态,文件操作,模板)

c基础学习第天&#xff08;多态&#xff0c;文件操作&#xff0c;模板&#xff09; 文章目录 1、多态1.1、多态的基本概念1.2、纯虚函数和抽象类1.3、虚析构和纯虚析构 2、文件操作2.1、文本文件2.1.1、写文件2.1.2、读文件 2.2、二进制文件2.2.1、写文件2.2.2、读文件 C提高编…

Python代码实现Excel表格转HTML文件

Excel工作簿是常用的表格格式&#xff0c;广泛用于组织、分析及展示数据。Excel文件通常需要专门的文档阅览器进行查看。如果我们想要以更兼容的方式展示Excel表格&#xff0c;可以将其转换为HTML格式&#xff0c;使其能够在各种浏览器中直接进行查看。同时&#xff0c;将Excel…

【小白入门篇1】GPT到底是怎样练成?

由于具有代表性的OpenAI公司GPT模型并没有开源&#xff0c;所以本章节是参考一些开源和现有课程&#xff08;李宏毅&#xff09;讲解ChatGPT原理。本章没有涉及到很多数学运算&#xff0c;比较适合小白了解GPT到底是怎么练成。GPT的三个英文字母分别代表Generative(生成式)&…

Git 分布式版本控制系统基本概念和操作命令

目录 Git 基本概念 功能特点 工作流程 操作命令 新建代码库 配置 增删文件 代码提交 分支 标签 查看信息 远程同步 撤销 其他 小结 Git Git 是一个开源的分布式版本控制系统&#xff0c;用于跟踪文件的变更历史。它最初由 Linux Torvalds 设计&#xff0c;用于…

php闭包应用

laravel 路由 bingTo 把路由URL映射到匿名回调函数上&#xff0c;框架会把匿名回调函数绑定到应用对象上&#xff0c;这样在匿名函数中就可以使用$this关键字引用重要的应用对象。Illuminate\Support\Traits\Macroable的__call方法。 自己写一个简单的demo: <?php <?…

Docker-Image

Docker Docker 镜像是什么为什么需要镜像镜像命令总览docker imagesdocker tagdocker pulldocker pushdocker rmidocker savedocker loaddocker image inspectdocker historydocker importdocker image prunedocker build Docker 镜像是什么 Docker image 本质上是一个 read-on…

每周编辑精选|在线运行 Deepmoney 金融大模型、AI 偏好等多个优质数据集上线

目前&#xff0c;AI 领域对金融模型的研究成果大多是基于公共知识进行训练的&#xff0c;但在实际的金融实践中&#xff0c;这些公共知识对于当前市场的可解释性往往严重不足。一个理想的金融大模型应该能够理解新闻或数据事件&#xff0c;并能够即时地从主观和量化两个角度对事…