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

【排序算法】②希尔排序

系列文章目录

第一篇:【排序算法】①直接插入排序-CSDN博客

第二篇:【排序算法】②希尔排序-CSDN博客

第三篇:【排序算法】③直接选择排序-CSDN博客

第四篇:【排序算法】④堆排序-CSDN博客


目录

系列文章目录

前言

一、希尔排序是什么?

算法思想

二、为什么希尔排序能做到排序?

三、实现希尔排序

四、分析希尔排序

总结



前言

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

为什么我们要学习排序?笔者认为有两点理由:一是面对浩如烟海的各种数据,我们应该学习如何分类、控制这些数据,而排序自然是少不了的;二是人类社会从古至今一直在“排序”,人与人之间,物与物之间,排序涉及到社会的方方面面。

学习并理解排序,不仅有助于工作学习,或许对一些其他方面的理解也会起动到推的效果。


一、希尔排序是什么?

希尔排序法又称缩小增量法,是在直接插入排序的基础上进行优化得来的排序算法。

算法思想

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

简单来说,希尔排序分为“预排序”和“正式排序”两步。


二、为什么希尔排序能做到排序?

这里笔者画了草图以帮助大家理解希尔排序:

假设我们排升序,数组为{7 ,1 ,3 ,9 ,6 ,5 ,4 ,8 ,2 ,0}

假设设gap=3:

此时将gap-1,在再上一次排序的基础上排:

gap=2,数组为{0,1,2,4,6,3,7,8,5,9}

再将gap-1,此时gap==1,实质上成为直接插入排序。

为什么要分几次预排序,然后还要调用直接插入排序?

还记得插入排序什么时候效率最高吗,当数组接近有序的时候!预排序的过程其实就是让数组接近有序,为后面的gap=1时的插入排序做准备,也就是说希尔排序的最后一步必须是gap==1时的直接插入排序!

三、实现希尔排序

void ShellSort(int* a, int n)
{if (!a)return;int gap = n;//gap>1:确保最后一趟gap==1while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < n - 1; i += gap){int end = i;int temp = a[end + gap];while (end >= 0&&end+gap<n){//if (temp > a[end])递减if(temp < a[end])//递增{a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = temp;}}
}

代码讲解:

①gap=gap/3,通过将gap/3快速将整个区间划分为多个小区间进行预处理操作。这里除以3是基于前人所做的大量总结中得出的最优解:在效率和计算复杂度间取得平衡。

若gap/2,则递减过慢且中间需要较多次的预排序过程;若gap/>3的数,则递减过快,难以达成预排序的目的:让数组变得尽量有序。

②gap=gap/3+1,这个+1的目的是确保gap永不小于 1,并且使得最后一次循环必定执行gap==1时的直接插入排序。

③for循环中实质为直接插入排序,在上一篇中已经介绍过,若读者有疑惑的地方欢迎在评论区讨论。


四、分析希尔排序

1. 希尔排序是对直接插入排序的优化。


2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。

3.时间复杂度:希尔排序的时间复杂度较难计算,需要用到数学中的概率论证明,这里就省略证明过程,希尔排序的时间复杂度随gap的变化而变化,上述代码中的gap=gap/3+1的时间复杂度为O(N^1.3);

4.空间复杂度为O(1);

5.稳定性分析:不稳定!希尔排序的不稳定性源于它在排序过程中会进行长距离的元素交换,这可能导致相同值的元素在排序后改变相对顺序。

比如:数组{5A, 2, 1 , 5B, 3}(5A和5B是值相同但需区分顺序的两个元素),希尔排序最后结果为{1,2,3,5B,5A},排序前5A在5B前,排序后5A在5B后!


总结

本文是【排序算法】系类第二篇,主要介绍了什么希尔排序,以及如何实现希尔排序,最后分析了希尔排序的特性。

希望对你有所帮助。

阅完点赞,手留余香~

http://www.xdnf.cn/news/1266373.html

相关文章:

  • 束搜索(Beam Search):原理、演进与挑战
  • AI鉴伪技术:守护数字时代的真实性防线
  • PromptPilot打造高效AI提示词
  • llama-factory代码详解(一)--model_args.py
  • C++实现MATLAB矩阵计算程序
  • 【传奇开心果系列】Flet框架实现的功能丰富设计现代化的管理仪表盘组件自定义模板
  • 掌握长尾关键词SEO优化技巧
  • Redis 持久化策略深度剖析:从原理到实战,守护数据不丢失
  • axios 发请求
  • 制作浏览器CEFSharp133+X86+win7 之 javascript交互(二)
  • C++-AVL树
  • 词向量基础:从独热编码到分布式表示的演进
  • 微软将于 10 月停止混合 Exchange 中的共享 EWS 访问
  • Codeforces 思维训练(二)
  • [激光原理与应用-206]:光学器件 - SESAM - 基本结构与工作原理
  • 爬虫攻防战:反爬与反反爬全解析
  • 跨境电商系统开发:ZKmall开源商城的技术选型与代码规范实践
  • sqli-labs通关笔记-第40关 GET字符型堆叠注入(单引号括号闭合 手工注入+脚本注入两种方法)
  • 多级缓存详解
  • 【能碳建设1】用AI+开源打造物联网+能碳管理+交易SaaS系统的最短路径实施指南
  • 软件定义车辆加速推进汽车电子技术
  • 快速使用selenium+java案例
  • [Linux]学习笔记系列 -- [arm][lds]
  • 2022 RoboCom 世界机器人开发者大赛-本科组(国赛)
  • 前端工程化:从构建工具到性能监控的全流程实践
  • 2G内存的服务器用宝塔安装php的fileinfo拓展时总是卡死无法安装成功的解决办法
  • Ubuntu下搭建LVGL模拟器
  • 【第2.1话:基础知识】基于Ubuntu的ROS环境搭建与车辆可视化编程实践:初学者指南及RVIZ应用(含作业及代码)
  • Ubuntu Server 22 虚拟机空间扩容
  • ubuntu dpkg命令使用指南