数据结构与算法-希尔排序

引言

        在计算机科学中,数据结构和算法是构建高效软件系统的基石。而排序算法作为算法领域的重要组成部分,一直在各种应用场景中发挥着关键作用。今天我们将聚焦于一种基于插入排序的改进版本——希尔排序(Shell Sort),深入了解其原理、实现步骤以及优缺点。

一、希尔排序简介

        希尔排序(Shell Sort) 是由Donald Shell在1959年提出的,它是对插入排序的一种改进,通过定义一个增量序列来对原始数据进行分组和预处理,使得每组内的数据相对有序,然后逐步减小增量并最终采用插入排序将所有数据完全排序。

二、希尔排序详细步骤

  1. 初始化增量序列:希尔排序的核心在于使用一系列的间隔(或称增量)对数组进行划分,初始时通常选择一个较大的间隔序列,例如 n/2, n/4, ..., 1(这里的 n 是数组长度)。

  2. 按增量分组排序:对于每一个增量值,将数组划分为多个子序列,每个子序列内部执行插入排序。例如,当增量为 gap 时,将从索引 0 到 gap-1 的元素作为一个子序列,然后是 gap 到 2gap-1 的元素,以此类推。

  3. 递减增量继续排序:重复上述过程,但每次减少一个增量,直到增量为1,此时整个数组被当作一个子序列进行插入排序,完成最后的排序工作。

三、希尔排序的时间复杂度与空间复杂度分析

  • 时间复杂度:希尔排序的时间复杂度取决于增量序列的选择,理论上最佳情况下可以达到O(n log n),但在实际应用中由于难以找到理想的增量序列,一般认为其平均时间复杂度介于O(n^1.3)到O(n^2)之间。

  • 空间复杂度:希尔排序是原地排序算法,不需要额外的存储空间,因此其空间复杂度为O(1)。

四、希尔排序的优缺点

优点

  • 相比于简单插入排序,希尔排序能显著提升对大规模无序数据集的排序效率。
  • 空间效率高,适合内存资源有限的情况。

缺点

  • 时间复杂度依赖于增量序列的选择,如果增量序列选择不当,可能会导致效率降低。
  • 希尔排序并不是稳定的排序算法,相等元素的顺序可能在排序过程中发生变化。

五、插入排序的图解过程 

图解小结  

        希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增了逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个数据恰被分为一组,算法便终止进行了。

六、希尔排序的代码实践  

1.展示每一次选择排序过程

//        第一轮
//        应为第一轮排序是将10个数据分成了10 /2 = 五组for (int i = 5; i < arr.length; i++) {
//            遍历各组中所有的元素(共有5组,每组两个元素,步长5)for (int j = i - 5; j >= 0; j -= 5) {
//                如果当前元素大于加上步长后的那个元素,说明需要交换if (arr[j] > arr[j + 5]) {int temp = arr[j];arr[j] = arr[j + 5];arr[j + 5] = temp;}}}System.out.println("第一轮希尔排序为");System.out.println(Arrays.toString(arr));//        第二轮
//        应为第二轮排序是将10个数据分成了5 /2 = 2组for (int i = 2; i < arr.length; i++) {
//            遍历各组中所有的元素(共有5组,每组两个元素,步长5)for (int j = i - 2; j >= 0; j -= 2) {
//                如果当前元素大于加上步长后的那个元素,说明需要交换if (arr[j] > arr[j + 2]) {int temp = arr[j];arr[j] = arr[j + 2];arr[j + 2] = temp;}}}System.out.println("第二轮希尔排序为");System.out.println(Arrays.toString(arr));//        第一轮
//        应为第一轮排序是将10个数据分成了2 /2 =1组for (int i = 1; i < arr.length; i++) {
//            遍历各组中所有的元素(共有5组,每组两个元素,步长5)for (int j = i - 1; j >= 0; j -= 1) {
//                如果当前元素大于加上步长后的那个元素,说明需要交换if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}System.out.println("第三轮希尔排序为");System.out.println(Arrays.toString(arr));

2.总结规律得到过程 

    public static void shellSort(int[] arr) {
//        有上述可得规律int temp = 0;int count = 0;for (int gap = arr.length / 2; gap > 0; gap /= 2) {count++;for (int i = gap; i < arr.length; i++) {
//                遍历各组中的元素共有gap组,步长为gapfor (int j = i - gap; j >= 0; j -= gap) {if (arr[j] > arr[j + gap]) {temp = arr[j];arr[j] = arr[j + gap];arr[j + gap] = temp;}}}System.out.printf("第%d轮希尔排序为", count);System.out.println(Arrays.toString(arr));}}

七、总结 

        虽然希尔排序在理论上的性能不如快速排序、归并排序等高级排序算法,但由于其简单且易于实现的特点,在某些特定场景下仍具有一定的实用价值,比如在硬件资源有限的嵌入式系统中,或者需要快速实现一个基础排序功能时。

        希尔排序是一种早期出现的改进型排序算法,它的提出启示我们可以通过对传统算法进行改良以适应不同的需求场景。尽管希尔排序在现代排序算法家族中并非最优解,但它在理解排序算法优化思路、探索更高效排序策略等方面依然具有重要的学习和研究价值。同时,希尔排序也是我们在实际编程中根据具体问题灵活选择排序算法的一个良好例证。

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

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

相关文章

smardaten数据报表功能全新上线,迎战“中国式报表”!

数据报表是企业业务数据统计分析最主要的应用方式之一。 面对复杂多元的报表结构、大量的数据处理需求时&#xff0c;“中国式报表”依然是业务人员、特别是财务人员进行数据统计分析的主要方式。虽然绝大多数企业都已部署高效的BI平台&#xff0c;但报表统计与可视化BI之间的…

接口测试—Postman详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、为何使用postman postman是一款简单高效的接口测试工具&#xff0c;能够很方便发送接口请求…

论文速览 | MobiSys 2018 | AIM: 通过智能手机实现声学成像 | AIM: Acoustic Imaging on a Mobile

无线感知/雷达成像部分最新工作<持续更新>: 链接地址 注1:本文系“无线感知论文速递”系列之一,致力于简洁清晰完整地介绍、解读无线感知领域最新的顶会/顶刊论文(包括但不限于 Nature/Science及其子刊; MobiCom, Sigcom, MobiSys, NSDI, SenSys, Ubicomp; JSAC, 雷达学报…

我的NPI项目之Android 安全系列 -- Keymaster到底是个什么

最近因为一直在调研独立secure element集成的工作&#xff0c;不巧的是目前使用的高通平台只有NFC-eSE的方案。高通目前也并不支持独立的eSE集成&#xff0c;codebase中并无相对应的代码。举个例子&#xff0c;目前使用的STM的一款eSE&#xff0c;但是这款eSE的开发STM还没有完…

TQ15EG开发板教程:创建运行petalinux2019.1

工程网盘链接&#xff1a;https://pan.baidu.com/s/1vFRpzmbifXt7GypU9aKjeg 提取码&#xff1a;0ylh 首先需要使用与petalinux相同版本的vivado创建工程&#xff0c;与之前不同的是在创建硬件设计时需要勾选上添加bit文件&#xff0c;所以要在生成bit文件之后再创建硬件设计…

【和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告

【&#x1f40b;和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告 文章目录 【&#x1f40b;和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告1 业务背景2 数据说明3 数据探索性分析4 用户行为分析4.1 用户属性与行为关系分析4.2 转化行为在不同用户属性群体中的分布…

基于springboot+vue的物流管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

#include “stdafx.h“代码的位置,导致编译通不过

1.先上代码: #include <iostream> //std::cout #include <iterator> //std::distance #include <list> //std::list using namespace std;#include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { list<int> mylist; …

R语言简介、环境与基础语法及注释

R语言简介、环境与基础语法及注释 一、R语言1.R语言简介2.R语言官网3.R语言中国的镜像网站4.R语言下载5.R语言的历史 二、R语言环境1.Windows安装1.1 去 R 语言下载的镜像站点的列表下载1.2 选择版本进行下载1.3 点击运行1.4 一路默认&#xff0c;安装完毕&#xff01; 2.Linux…

【IO】进程间通信

A程序代码&#xff1a; #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <string.h> int main(int argc, const char *argv[]) {if(mkfifo…

sql 查询

连续区域取数 select sid,min(b.eid) as eid from (select id2 as sid from txtTempTable where tc1 like Name*) as a, (select id as eid from txtTempTable where tc1Page) as b where sid<b.eid group by sid 16,18, 22,23 id tc1tc21617182223 两表对应关…

Tomcat部署及多实例(一)

一、Tomcat简介 1、简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。 当在一台机器上配置好Apache 服务器&#xff0c…