【排序算法】二、希尔排序(C/C++)

「前言」文章内容是排序算法之希尔排序的讲解。(所有文章已经分类好,放心食用)

「归属专栏」排序算法

「主页链接」个人主页

「笔者」枫叶先生(fy)

目录

  • 希尔排序
    • 1.1 原理
    • 1.2 代码实现(C/C++)
    • 1.3 特性总结

希尔排序

1.1 原理

希尔排序是一种基于直接插入排序的排序算法,也称为“缩小增量排序”

希尔排序法的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序

希尔排序:基于数组(顺序表)的结构进行排序

希尔排序的由来

希尔排序是按其设计者希尔的名字命名的

他对普直接入排序的时间复杂度进行分析,得出了以下结论:

  1. 直接插入排序的时间复杂度最坏情况下为O(N^2),此时待排序列为逆序,或者说接近逆序
  2. 直接插入排序的时间复杂度最好情况下为O(N),此时待排序列为升序,或者说接近升序

于是希尔就想:若是能先将待排序列进行一次预排序,使待排序列接近有序(接近我们想要的顺序),然后再对该序列进行一次直接插入排序,此时已经排好序了,并且时间复杂度也降低了

希尔排序 = 预排序 + 一次直接插入排序

因为此时直接插入排序的时间复杂度为O(N)(直接插入排序对排序的数组接近有序的时候,时间复杂度为O(1)),那么只要控制预排序阶段的时间复杂度不超过O(^2),那么整体的时间复杂度就比直接插入排序的时间复杂度低了

希尔排序的步骤如下:

  1. 首先选择一个增量序列,通常选择增量序列gap为n/2,n/4,n/8...1,其中n为数组的长度
  2. 根据增量序列将数组分成若干个子序列,对每个子序列进行插入排序
  3. 逐渐缩小增量序列,重复步骤2,直到增量为1,即对整个数组进行一次插入排序

例如,对该数组使用希尔排序进行排序(升序)
在这里插入图片描述

取第一次增量gap为:gap = 10/2,10为数组大小,此时相隔距离为5的元素被分为一组(共分了5组,每组有2个元素),然后分别对每一组进行直接插入排序
在这里插入图片描述
取第二次增量gap为:gap = 5/2,5为第一次增量值,此时相隔距离为2的元素被分为一组(共分了2组,每组有5个元素),然后再分别对每一组进行直接插入排序
在这里插入图片描述
取第三次增量gap为:gap = 2/2,2为第二次增量值,此时gap为1,即整个序列被分为一组,进行一次直接插入排序(对整个数组)
在这里插入图片描述
动图演示如下:
在这里插入图片描述

为什么要让gap由大到小?

  • gap越大,数据挪动得越快;gap越小,数据挪动得越慢
  • 前期让gap较大,可以让数据更快得移动到自己对应的位置附近,减少挪动次数

:一般情况下,取序列的一半作为增量,然后依次减半,直到增量为1(也可自己设置)

希尔排序的时空复杂度

希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在不同的书中给出的希尔排序的时间复杂度都不固定
在这里插入图片描述
在这里插入图片描述
Knuth序列是一种希尔排序中常用的增量序列,由Donald Knuth提出。Knuth序列的计算公式为:h = 3h + 1,其中h是增量序列的值,下面代码gap使用这个公式(有兴趣自己了解)

Knuth进行了大量的试验统计,暂时就按照:O(N^1.25)O(1.6 * N^1.25)来算,按O(N^1.3)计算(最好情况下)

  • 希尔排序时间复杂度O(N*logN) ~ O(N^2),以2为底,最好O(N^1.3),最坏 O(N^2)
  • 希尔排序空间复杂度O(1)

1.2 代码实现(C/C++)

C语言代码如下:(升序)

// 希尔排序(基于直接插入排序)
void ShellSort(int* arr, int n) // arr:需要排序的数组; n:数组的大小
{
	int gap = n;
	while (gap > 1)
	{
		// gap 大于 1, 进行预排序
		// gap == 1, 相当于直接插入排序(注:循环进来 gap 经过 gap = gap / 3 + 1 这才变成 1 )
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; ++i)
		{
			int end = i; // 记录有序列的最后一个下标
			int tmp = arr[end + gap]; // 保存等待插入的值

			while (end >= 0)
			{
				if (arr[end] > tmp) // arr[end]比要插入的数大,向后移动
				{
					arr[end + gap] = arr[end]; // 向后移,进行覆盖,tmp已经保存被覆盖的值
					end -= gap;
				}
				else // arr[end]比要插入的数小,已有序,跳出循环
				{
					break; 
				}
			}
			arr[end + gap] = tmp; // 进行插入
		}
	}
}

C++代码:(升序)

// 希尔排序(基于直接插入排序)
void ShellSort(vector<int>& arr)
{
	int n = arr.size();
	int gap = n;
	while (gap > 1)
	{
		// gap 大于 1, 进行预排序
		// gap == 1, 相当于直接插入排序(注:循环进来 gap 经过 gap = gap / 3 + 1 这才变成 1 )
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; ++i)
		{
			int end = i; // 记录有序列的最后一个下标
			int tmp = arr[end + gap]; // 保存等待插入的值

			while (end >= 0)
			{
				if (arr[end] > tmp) // arr[end]比要插入的数大,向后移动
				{
					arr[end + gap] = arr[end]; // 向后移,进行覆盖,tmp已经保存被覆盖的值
					end -= gap;
				}
				else // arr[end]比要插入的数小,已有序,跳出循环
				{
					break;
				}
			}
			arr[end + gap] = tmp; // 进行插入
		}
	}
}

1.3 特性总结

希尔排序的特性总结

  • 希尔排序是对直接插入排序的优化
  • gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。整体而言,可以达到优化的效果
  • 希尔排序时间复杂度O(N*logN) ~ O(N^2),以2为底
  • 空间复杂度O(1)
  • 稳定性:不稳定

--------------------- END ----------------------

「 作者 」 枫叶先生
「 更新 」 2024.1.9
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React-组件使用与组件通信

生命周期补充(不常用): 案例&#xff1a; import React, { Component } from reactexport default class App extends Component {state {num : 100,list: []}//获取到的是更新前的props 和 state getSnapshotBeforeUpdate(prevProps,prevState){ //必须搭配componentDidUpd…

红队打靶练习:DERPNSTINK: 1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto 5、whatweb 目录探测 1、gobuster 2、dirsearch WEB get flag1 robots.txt /php/phpmyadmin /temporary /weblog wordpress wpscan扫描 漏洞发现 提权 系统信息收集 mysql登录 john get flag2 s…

Orchestrator源码解读2-故障失败发现

目录 目录 前言 核心流程函数调用路径 GetReplicationAnalysis 故障类型和对应的处理函数 拓扑结构警告类型 与MHA相比 前言 Orchestrator另外一个重要的功能是监控集群&#xff0c;发现故障。根据从复制拓扑本身获得的信息&#xff0c;它可以识别各种故障场景。Orchest…

Vue2.v-指令

v-if 在双引号中写判断条件。 <div v-if"score>90">A</div> <div v-else-if"score>80">B</div> <div v-else>C</div>v-on: :冒号后面跟着事件。 为了简化&#xff0c;可以直接用代替v-on:。 事件名“内联语…

【前端素材】同城服务分类手机APP页面的设计实现

一、需求分析 一个同城服务分类手机页面是一个用于提供同城服务分类信息的移动设备页面。它通常具有以下功能&#xff1a; 地理定位&#xff1a;同城服务分类手机页面可以利用用户的地理定位功能&#xff0c;获取用户当前所在的城市或地区信息&#xff0c;以便提供与用户所在地…

一、Mybatis 简介

本章概要 简介持久层框架对比快速入门&#xff08;基于Mybatis3方式&#xff09; 1.1 简介 https://mybatis.org/mybatis-3/zh/index.html MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投G…

12、DolphinScheduler

1、DolphinScheduler简介 1.1、 DolphinScheduler概述 Apache DolphinScheduler是一个分布式、易扩展的可视化DAG工作流任务调度平台。致力于解决数据处理流程中错综复杂的依赖关系&#xff0c;使调度系统在数据处理流程中开箱即用。 1.2、 DolphinScheduler核心架构 Dolph…

UV贴图和展开初学者指南

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 介绍 这正是本文的主题——UV贴图——登上舞台的时候。大多数 3D 建…

基于YOLOv8 + BotSORT实现球员和足球检测与跟踪 (步骤 + 源码)

导 读 本文主要介绍基于YOLOv8和BotSORT实现球员和足球检测与跟踪 &#xff0c;并给出步骤和代码。 背景介绍 本文旨在了解 YOLO 架构并在自定义数据集上对其进行训练&#xff0c;然后微调模型以获得更好的结果&#xff0c;并运行推理以了解最有效的方法。 什么是YOLO&#x…

练习-指针笔试题

目录 前言一、一维整型数组1.1 题目一1.2 题目二 二、二维整型数组2.1 题目一2.2 题目二2.3 题目三 三、结构体3.1 题目一&#xff08;32位机器运行&#xff09; 四、字符数组4.1 题目一4.2 题目二 总结 前言 本篇文章记录关于C语言指针笔试题的介绍。 一、一维整型数组 1.1 …

探索人工智能:深度学习、人工智能安全和人工智能

深度学习是人工智能的一种重要技术&#xff0c;它模拟了人类大脑神经网络的工作原理&#xff0c;通过建立多层次的神经元网络来实现对数据的分析和处理。这种技术的引入使得人工智能的发展进入到了一个新的阶段。 现如今&#xff0c;深度学习在各个领域都有着广泛的应用。例如…

简单的MOV转MP4方法

1.下载腾讯的QQ影音播放器, 此播放器为绿色视频播放器, 除了播放下载好的视频外没有臃肿无用功能 官网 QQ影音 百度网盘链接&#xff1a;https://pan.baidu.com/s/1G0kSC-844FtRfqGnIoMALA 提取码&#xff1a;dh4w 2.用QQ影音打开MOV文件 3.右下角打开影音工具箱 , 选择截取…

开启Android学习之旅-6-实战答题App

不经过实战&#xff0c;看再多理论&#xff0c;都是只放在笔记里&#xff0c;活学活用才是硬道理。同时开发应用需要循序渐进&#xff0c;一口气规划300个功能&#xff0c;400张表&#xff0c;会严重打击自己的自信。这里根据所学的&#xff0c;开发一个答题App。 题库需求分析…

公司新买的BI,和金蝶系统配合太默契了

公司一直都用金蝶系统来实现包括财务管理、供应链管理、人力资源管理等多个方面的资源的合理配置和业务流程的自动化。但到了数据分析这块&#xff0c;金蝶系统就明显力不从心&#xff0c;需要一个专业的数据分析工具来接手。财务经理推荐用奥威BI&#xff0c;说这款BI的一大特…

光纤知识总结

1光纤概念&#xff1a; 光导纤维&#xff08;英语&#xff1a;Optical fiber&#xff09;&#xff0c;简称光纤&#xff0c;是一种由玻璃或塑料制成的纤维&#xff0c;利用光在这些纤维中以全内反射原理传输的光传导工具。 微细的光纤封装在塑料护套中&#xff0c;使得它能够…

OpenAI ChatGPT-4开发笔记2024-01:开发环境

ChatGPT发展一日千里。工具、函数少则数日&#xff0c;多则数月就加入了Deprecated行列不再如预期般工作。元旦闲来无事&#xff0c;用最新的ChatGPT重写一下各种开发场景&#xff0c;全部实测通过。 开发环境&#xff1a; 电脑&#xff1a;两台笔记本&#xff1a;HP和MacBoo…

Pixi.js的魅力

摘要&#xff1a;官网 Web开发的时代&#xff0c;图形和动画已经成为了吸引用户注意力的重要手段之一。而 Pixi.js 作为一款高效、易用的2D渲染引擎&#xff0c;已经成为了许多开发者的首选~~ 项目中&#xff0c;有一些图像的处理操作&#xff08;3D图&#xff0c;2D图都有&…

49寸OLED拼接屏:技术、应用与市场前景

作为“49寸OLED拼接屏”技术总监&#xff0c;我深知这一产品对于显示行业的重要性。随着显示技术的不断进步&#xff0c;OLED拼接屏在高端显示市场占据了一席之地。下面&#xff0c;我将从技术的角度深入剖析这一产品。 一、参数 49寸OLED拼接屏是一款高端大屏显示产品&#x…

在线文本转语音工具的实现

文章目录 文章最下面有工具链接&#xff01;前言edge-tts库1.首先使用pip安装这个库2.写一段示例代码3.多线程 pydub库1.介绍2.示例 将他们整合起来我把他们部署到了我的服务器上&#xff0c;可以在线使用点我使用工具 文章最下面有工具链接&#xff01; 前言 最近有文字转语…

Halcon3D篇-3D预处理,滤波,点云筛选

前言 由于3D相机采集到的数据通常通过Tiff格式的深度图进行显示或者保存。 深度图与模型的互转可以访问另一篇博客&#xff1a;https://blog.csdn.net/m0_51559565/article/details/135362674 关于3D相机的数据采集&#xff0c;可以访问我们另一篇关于LMI3D相机SDK的二次开发…