数据结构的希尔排序(c语言版)

一.希尔排序的概念

1.希尔排序的基本思想

希尔排序是一种基于插入排序算法的优化排序方法。它的基本思想如下:

  1. 选择一个增量序列 t1,t2,......,tk,其中 ti > tj, 当 i < j,并且 tk = 1。

  2. 按增量序列个数k,对数组进行k趟排序:

    • 第一趟,按 t1 的增量对数组进行插入排序;
    • 第二趟,按 t2 的增量对数组进行插入排序;
    • ... ...
    • 第k趟,按 tk 的增量(此时 tk = 1),也就是对整个数组进行插入排序。

2.希尔排序的优点

  1. 时间复杂度较低。希尔排序的时间复杂度一般在 O(n^1.25) 和 O(n^1.5) 之间,优于简单的插入排序。

  2. 在部分有序的数组中效率很高。希尔排序通过分组插入排序来利用数据的局部有序性,可以有效地加快排序速度。

  3. 空间复杂度低,只需要常量级的额外空间。

  4. 代码实现相对简单,易于理解和编码。

3.希尔排序的缺点

  1. 增量序列的选择对排序效率有很大影响。不同的增量序列会导致很大的性能差异。找到最优的增量序列是一个难题。

  2. 在数据量很大时,性能可能不如其他算法,如快速排序、堆排序等。

  3. 不稳定。希尔排序是不稳定的排序算法,即相等的元素可能会改变相对次序。

  4. 理论分析复杂。希尔排序的时间复杂度分析比较困难,没有得到一个统一的结论。

4.希尔排序与快速排序在使用情况时的差异 

  1. 数据量中等且部分有序:

    • 希尔排序通过分组排序利用了数据的局部有序性,在部分有序的数组上表现很好。
    • 而快速排序在部分有序数组上可能会退化为 O(n^2) 的时间复杂度。
  2. 内存受限的环境:

    • 希尔排序只需要常量级的额外空间,而快速排序需要递归调用栈,在内存受限的环境下可能会有优势。
  3. 数据分布不均匀:

    • 快速排序的性能很容易受到数据分布的影响,而希尔排序相对更加好。
  4. 预先知道数据大致分布情况:

    • 如果对数据的分布有一定了解,可以选择合适的增量序列来优化希尔排序的性能。
  5. 对稳定性要求不高:

    • 快速排序是不稳定的,而希尔排序也是不稳定的。如果稳定性不是关键,希尔排序可能是更好的选择。

二.希尔排序的功能

1.分组插入排序

  • 希尔排序的核心思想是通过分组插入排序来优化基本的插入排序算法。
  • 它首先选择一个增量序列,如 [n/2, n/4, n/8, ...],将原始数组划分为多个子数组。
  • 每个子数组的元素索引差为增量值。例如,当增量为 4 时,子数组为 arr[0]、arr[4]、arr[8]...
  • 对这些子数组分别进行插入排序。
  • 随着增量序列逐步减小,子数组中的元素越来越集中,最终整个数组被完全排序。

2.利用局部有序性

  • 在初始阶段,当增量较大时,子数组中的元素较为分散。
  • 随着增量的不断减小,子数组中的元素逐渐趋于有序。
  • 这种分组插入排序可以有效利用数据的局部有序性,从而减少插入排序的比较和移动操作次数。

3.时间复杂度优化

  • 基本插入排序的时间复杂度为 O(n^2)。
  • 而希尔排序通过分组插入排序和利用局部有序性,可以将平均时间复杂度优化到 O(n^1.25) 到 O(n^1.5)。

4.空间复杂度低

  • 希尔排序只需要常量级的额外空间来存储一些中间变量,如增量序列等。
  • 因此它的空间复杂度很低,仅为 O(1)。

5.代码实现简单

  • 与其他高效排序算法相比,如快速排序和归并排序,希尔排序的代码实现较为简单。
  • 它只需要一个嵌套循环来完成分组和插入排序即可。

三.希尔排序的代码实现

1.排序的实现

  1. 定义一个名为 shell_sort 的函数,它接受两个参数:

    • arr: 一个整型数组,需要被排序
    • n: 数组的长度
  2. shell_sort 函数的实现:

    • 使用一个 for 循环来遍历不同的增量值 gap。初始的 gap 为 n/2
    • 对于每个 gap 值,我们再次使用一个 for 循环来遍历数组。
    • 对于每个元素 arr[i],我们将其暂存到临时变量 temp 中。
    • 然后,我们使用另一个内层 for 循环来执行分组插入排序。在这个循环中,我们将 arr[j] 的值移动到 arr[j - gap] 的位置,直到找到 temp 应该插入的位置。
    • 最后,我们将 temp 赋值给 arr[j]
    • 重复上述过程,直到 gap 变为 0。
void shell_sort(int arr[], int n) {for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}

2.main函数

  • 定义一个示例数组 arr
  • 计算数组长度 n
  • 打印出未排序的数组。
  • 调用 shell_sort 函数对数组进行排序。
  • 打印出排序后的数组。
int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);printf("Unsorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");shell_sort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

3.程序的执行流程

  • 首先,在 main 函数中,我们定义了一个示例数组 arr
  • 然后,我们计算数组的长度 n
  • 接下来,我们打印出未排序的数组。
  • 调用 shell_sort 函数对数组进行排序。
  • 在 shell_sort 函数内部,我们使用一个 for 循环来迭代不同的增量值 gap。初始的 gap 为 n/2
  • 对于每个 gap 值,我们遍历数组,对于每个元素 arr[i],我们将其暂存到临时变量 temp 中。
  • 然后,我们使用另一个内层 for 循环来执行分组插入排序。在这个循环中,我们将 arr[j] 的值移动到 arr[j - gap] 的位置,直到找到 temp 应该插入的位置。
  • 最后,我们将 temp 赋值给 arr[j]
  • 重复上述过程,直到 gap 变为 0。
  • 排序完成后,我们在 main 函数中打印出排序后的数组。

四.希尔排序的源代码

  1. 首先,我们定义一个 shell_sort 函数,接受一个整型数组 arr 和数组长度 n 作为参数。
  2. 在函数内部,我们使用一个 for 循环来迭代不同的增量值 gap。初始的 gap 为 n/2
  3. 对于每个 gap 值,我们遍历数组,对于每个元素 arr[i],我们将其暂存到临时变量 temp 中。
  4. 然后,我们使用另一个内层 for 循环来执行分组插入排序。在这个循环中,我们将 arr[j] 的值移动到 arr[j - gap] 的位置,直到找到 temp 应该插入的位置。
  5. 最后,我们将 temp 赋值给 arr[j]
  6. 重复上述过程,直到 gap 变为 0。
#include <stdio.h>void shell_sort(int arr[], int n) {for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);printf("Unsorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");shell_sort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

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

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

相关文章

接口测试及接口测试常用的工具详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息…

智能界面设计:数字孪生与大数据结合的美学典范

智能界面设计&#xff1a;数字孪生与大数据结合的美学典范 引言 在数字化浪潮的推动下&#xff0c;智能界面设计成为了连接用户与技术的重要桥梁。数字孪生技术与大数据的结合&#xff0c;不仅为UI设计带来了前所未有的创新机遇&#xff0c;更成为了美学与功能性融合的典范。…

[Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件

如下&#xff0c;我们有一个platform.pk8和platform.x509.pem。为了打包&#xff0c;需要将私钥&#xff08;.pk8&#xff09;和公钥证书&#xff08;可能是.pem或.crt文件&#xff09;合并成一个PKCS#12 格式的密钥库文件 1.准备你的私钥和证书文件 确保你有以下两个文件&…

rk3568_mutex

文章目录 前言1、什么是mutex?1.1mutex互斥体API函数二、实验2.1实验目的2.2源码2.3结果图前言 本文记录的是rk3568开发板基础上做的mutex实验 1、什么是mutex? mutex是互斥体,它是比信号量semaphore更加专业的机制。 在我们编写Linux驱动的时候遇到需要互斥的地方建议使用…

JMH304-剑侠情缘2网络版+2017纹饰端+翅膀+单机+外网整理+各种副本

资源介绍&#xff1a; 藏剑-太虚-梁山-杀手堂种树地宫师门纹饰装备长流云阳套等等———– 做登录器联系站长 资源截图&#xff1a; 下载地址

springcloud-服务拆分与远程调用

一 微服务 1.1简单了解 SpringCloud SpringCloud是目前国内使用最广泛的微服务框架。官网地址&#xff1a;Spring Cloud。 SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&#xff0c;从而提供了良好的开箱即用体验&#xff1a…

泰达克TADHE uv胶水在粘接聚酰亚胺(Polyimide,PI)时具有一些优势,并在各行业中得到了广泛应用,尤其是在特定应用中

泰达克TADHE uv胶水在粘接聚酰亚胺&#xff08;Polyimide&#xff0c;PI&#xff09;时具有一些优势&#xff0c;并在各行业中得到了广泛应用&#xff0c;尤其是在特定应用中。以下是一些使用UV胶水粘接PI的优势&#xff1a; 1.快速固化&#xff1a; UV胶水通过紫外线照射进行固…

材料物理 笔记-9

原内容请参考哈尔滨工业大学何飞教授&#xff1a;https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》&#xff08;哈尔滨工业大学出版社&#xff09; ——…

央视网视频下载和花屏问题处理

央视网(www.cctv.com)视频下载往往是花屏的&#xff0c;如何处理呢&#xff1f; 如果您是IT技术开发者&#xff0c;那么您可以通过下面步骤自己实现。 用chrome浏览器&#xff0c;F2打开开发者工具&#xff0c;找到当前页面的network 然后找一个接口&#xff1a;https://vdn.a…

详解Java ThreadLocal

个人博客 详解Java ThreadLocal | iwts’s blog Java ThreadLocal ThreadLocal提供了线程内存储变量的能力&#xff0c;这些变量不同之处在于每一个线程读取的变量是对应的互相独立的。通过get和set方法就可以得到当前线程对应的值。 TreadLocal存储模型 ThreadLocal的静态…

MySQL 重启之后无法写入数据了?

数据库交接后因 persist_only 级别的参数设置引发的故障分析。 作者&#xff1a;不吃芫荽&#xff0c;爱可生华东交付服务部 DBA 成员&#xff0c;主要负责 MySQL 故障处理及相关技术支持。 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系…

听说部门来了个00后测试开发,一顿操作给我整麻了

公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&#xff01…

装机必备——360压缩安装教程

装机必备——360压缩安装教程 软件下载 软件名称&#xff1a;360压缩 软件语言&#xff1a;简体中文 软件大小&#xff1a;3.38M 系统要求&#xff1a;Windows7或更高&#xff0c; 32/64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM4G或更高 下载通道①迅雷云盘丨…

【加密与解密(第四版)】第十四章笔记

第十四章 漏洞分析技术 14.1 软件漏洞原理 缓冲区溢出漏洞&#xff1a;栈溢出 堆溢出、整型溢出&#xff08;存储溢出、计算溢出、符号问题&#xff09; UAF&#xff08;Use-After-Free&#xff09;漏洞 14.2 ShellCode 功能模块&#xff1a;下载执行、捆绑、反弹shell 14.3 …

牛客NC334 字典序第K小【困难 10叉树 Java/Go/PHP/C++】,力扣 440. 字典序的第K小数字

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/670c2bda374241d7ae06ade60de33e8b https://leetcode.cn/problems/k-th-smallest-in-lexicographical-order/description/ 本答案核心 10叉树, 数学规律Java代码 import java.util.*;public class Solution {…

大学搜题软件音乐类?分享三个支持答案和解析的工具 #微信#媒体

高效的学习工具可以帮助我们提高记忆力和理解能力&#xff0c;使知识更加深入人心。 1.彩虹搜题 这是个微信公众号 一款专门供全国大学生使用的查题神器!致力于帮助大学生解决学习上的难题,涵盖了大学生学习所需的学习资料。 下方附上一些测试的试题及答案 1、甲、乙合伙开…

IP协议说明

文章目录 前言一、IP协议的简介二、IP数据报1.IP 数据报结构2.IP 数据报的分片解析3.IP 数据报的分片重装 三、IP 数据报的输出四、IP 数据报的输入 前言 IP 指网际互连协议&#xff0c; Internet Protocol 的缩写&#xff0c;是 TCP/IP 体系中的网络层协议。设计 IP 的目的是…

【AI算法岗面试八股面经【超全整理】——机器学习】

AI算法岗面试八股面经【超全整理】 概率论信息论机器学习深度学习CVNLP 目录 1、回归损失函数2、分类损失函数3、误差&#xff08;Error&#xff09;、偏差&#xff08;Bias&#xff09;、方差&#xff08;Variance&#xff09;4、PCA&#xff08;Principle Component Analysi…

QT学习(20):QStyle类

Qt包含一组QStyle子类&#xff0c;这些子类&#xff08;QWindowsStyle&#xff0c;QMacStyle等&#xff09;模拟Qt支持的不同平台的样式&#xff0c;默认情况下&#xff0c;这些样式内置在Qt GUI模块中&#xff0c;样式也可以作为插件提供。 Qt的内置widgets使用QStyle来执行几…

美光EMMC芯片丝印型号查询 8LK17/D9PSK, OXA17/JY997

问题说明 最近在使用美光EMMC的时候&#xff0c;发现通过芯片丝印查询不到 芯片的规格说明书&#xff1b; 经过查阅资料&#xff0c;发现美光的EMMC芯片 “由于空间限制&#xff0c;FBGA 封装组件具有与部件号不同的缩写部件标记”&#xff0c;需要通过官网查询丝印的FBGA cod…