【排序算法】二、希尔排序(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.mzph.cn/news/609616.shtml

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

相关文章

数据结构-测试1

一、判断题 1.队列中允许插入的一端叫队头&#xff0c;允许删除的一端叫队尾&#xff08;F&#xff09; 队列中允许删除的一端叫队头&#xff08;front&#xff09;,允许插入的一端叫队尾&#xff08;rear&#xff09; 2. 完全二叉树中&#xff0c;若一个结点没有左孩子&#…

Developer Tools for Game Creator 1

插件包含: 持久世界时间管理系统 单击以生成对象或预设 游戏内调试控制台 游戏内事件控制台 控制台管理控制 命令模板脚本 游戏内屏幕截图 低分辨率和高分辨率图像 缩略图生成 移动支持 使用Game Creator Action或拖放来激活和控制组件,无需编码。 通过此资产,您可以获得: …

初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(1)

文章目录 &#x1f3c6; 初识 Elasticsearch 应用知识&#x1f50e; 初识 Elasticsearch 应用知识(1)&#x1f341;&#x1f341; 01、什么是 Elasticsearch&#xff1f;&#x1f341;&#x1f341; 02、能列出 10 个使用 Elasticsearch 作为其搜索引擎或数据库的公司吗&#x…

2023 年度合辑 | 出海大年的全球化产品洞察和服务动向

2023 年度合辑 年度关键词 出海&全球化 出海 & 全球化通信服务全面升维 出海大年&#xff0c;融云全球互联网通信云作为“全球化最佳基础设施”之一&#xff0c;发挥技术沉淀和实践积累带来的核心优势&#xff0c;结合市场变化对出海 & 全球化通信服务进行了全方位…

李沐之神经网络基础

目录 1.模型构造 1.1层和块 1.2自定义块 1.3顺序块 1.4在前向传播函数中执行代码 2.参数管理 2.1参数访问 2.2参数初始化 3.自定义层 3.1不带参数的层 3.2带参数的层 4.读写文件 4.1加载和保存张量 4.2加载和保存模型参数 1.模型构造 1.1层和块 import torch fr…

c JPEG编码,但有错误

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/videodev2.h> //v4l2 头文件 #include <strin…

MySQL之数据的导入、导出远程备份

目录 一. navicat的导入、导出 1.1 导入 1.2 导出 二. mysqldump命令导入、导出 2.1 导出 2.2 导入 三. LOAD DATA INFILE 命令导入、导出 3.1 设置 3.2 导出 3.3 导入 3.4 查看secure_file_priv设置 四. 远程备份 4.1 导出 4.2 导入 五. 思维导图 一. navicat的导入、导…

podman configure insecure certificate registry【podman 设置非安全镜像仓库】

预备条件 docker registry仓库私搭并配置证书centos 7.9 部署 harbor 镜像仓库实践harbor 部署入门指南Podman 部署私有镜像仓库 设置 $ vim /etc/hosts 192.168.23.47 registry.ghostwritten.com$ vim /etc/containers/registries.conf ... [[registry]] location "r…

7.2 1D PARALLEL CONVOLUTION—A BASIC ALGORITHM

正如我们在第7.1节中提到的&#xff0c;所有输出&#xff08;P&#xff09;元素的计算可以在卷积中并行完成。这使得卷积成为并行计算的理想问题。根据我们在矩阵-矩阵乘法方面的经验&#xff0c;我们可以快速编写一个简单的并行卷积内核。为了简单起见&#xff0c;我们将从1D卷…

【liunx】线程池+单例模式+STL,智能指针和线程安全+其他常见的各种锁+读者写者问题

线程池单例模式STL,智能指针和线程安全其他常见的各种锁读者写者问题 1.线程池2.线程安全的单例模式3.STL,智能指针和线程安全4.其他常见的各种锁4.读者写者问题 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.线程池 目前我们学了挂起等待锁、条件变量、信…

【排序算法】一、排序概念和直接插入排序(C/C++)

「前言」文章内容是排序算法之直接插入排序的讲解。&#xff08;所有文章已经分类好&#xff0c;放心食用&#xff09; 「归属专栏」排序算法 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、排序概念的介绍二、直接插入排序2.1 原理2.2 代码实现&#xff08;C/C&#xf…

Linux的网络设置

一.查看网络配置 1.查看网络接口信息 - ifconfig ① 直接使用 ifconfig 命令 默认显示活动的网卡 解析&#xff1a; ② ifconfig 具体网卡名称 只显示具体的网卡的信息 ③ ifconfig -a 显示所有的网卡 ④ ifconfig 网卡名称 down 关闭网卡 ifdown 关闭网卡 …

2024年01月微软更新Bug 已解决 !Explorer.EXE 提示:Windows无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目。

前倾概要 近期大量出现如上图问题&#xff0c;杀毒&#xff0c;系统急救箱都没反应&#xff0c;罪魁祸首就是微软更新&#xff01; 点击什么都是&#xff1a;Windows无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目。 但软件使用正常&#xff0c;还能通过建立…

【产品应用】一体化伺服电机在管道检测机器人中的应用

一体化伺服电机在管道检测机器人的应用正日益受到关注。管道检测机器人是一种能够在管道内部进行检测和维护的智能化设备&#xff0c;它可以检测管道的内部结构、泄漏、腐蚀等问题&#xff0c;以确保管道的安全和稳定运行。而一体化伺服电机作为机器人的动力源&#xff0c;对于…

20230403读书笔记|《苏轼词集》——试问岭南应不好,此心安处是吾乡

20230403读书笔记|《苏轼词集》——试问岭南应不好&#xff0c;此心安处是吾乡 导读卷一卷二卷三 在书架里加了好几本苏轼词集&#xff0c;很多词是重复的&#xff0c;但这并不影响多读几本&#xff0c;苏轼的词豪迈大气&#xff0c;豁达爽朗&#xff0c;蛮值得一读的。有不少都…

中小型家具制造业使用制造管理MES系统应该注意什么?

随着人们生活水平变高&#xff0c;人们对家具的要求也在提高。为了应对越来越高的要求&#xff0c;企业开始寻找更有效的方法&#xff0c;其中就包括mes系统&#xff0c;那么中小型家具企业在使用mes的过程中应该注意什么呢&#xff1f; 第一&#xff0c;要考虑选择什么样的mes…

【数据结构】二叉树的链式实现

树是数据结构中非常重要的一种&#xff0c;在计算机的各方个面都有他的身影 此篇文章主要介绍二叉树的基本操作 目录 二叉树的定义&#xff1a;二叉树的创建&#xff1a;二叉树的遍历&#xff1a;前序遍历&#xff1a;中序遍历&#xff1a;后序遍历&#xff1a;层序遍历&#…

Mendeley Word 文献引用

这里写目录标题 1. 下载Mendeley 并插入到Word1.1 下载安装1.2 在Word 中添加Mendeley 插件文献引用相关 1. 下载Mendeley 并插入到Word 1.1 下载安装 Mendeley 官网下载 1.2 在Word 中添加Mendeley 插件 打开 Mendeley&#xff0c;点击 Tools —>Install Mendeley Cite…

AWS云用户创建

问题 需要给工友创建AWS云的用户&#xff0c;这里假设使用分配给自己AWS开发者IAM账号&#xff0c;给别人创建aws IAM账号。 登录系统 打开页面&#xff1a;https://xxx.signin.aws.amazon.com/console&#xff0c;使用分配的开发者账号登录。如下图&#xff1a; 创建用户…

vue组件开发

1. 组件开发介绍 ① 组件化&#xff1a;一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为。 好处&#xff1a;便于维护&#xff0c;利于复用 → 提升开发效率。 组件分类&#xff1a;普通组件、根组件。② 根组件&#xff08;App.vue&#xf…