数据结构的希尔排序(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.mzph.cn/web/17747.shtml

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

相关文章

Centos安装,window、ubuntus双系统基础上安装Centos安装

文章目录 前言一、准备工作二、开始安装1、2、首先选择DATE&TIME2、选择最小安装3、 选择安装位置 总结 前言 因工作需要&#xff0c;我需要在工控机上额外装Centos7系统&#xff0c;不过我是装在机械硬盘上了不知道对性能是否有影响&#xff0c;若有影响&#xff0c;后面…

基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善

前言 紧接上篇->基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善-CSDN博客 本篇将完善主界面的管理员入库和出库功能&#xff0c;同样的&#xff0c;管理员入库和出库的设计套路适用于动态表的录入和编辑 首先还是介绍一下本项目将要实现的功能 &#xf…

[Android]项目打包APK时报错PKCS12 keystore not in version 3 format

报错&#xff1a; PKCS12 keystore not in version 3 format Execution failed for task :app:packageRelease. > A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable > com.android.ide.commo…

如何为个人网站部署SSL安全证书,以实现网站的 HTTPS 加密协议访问?

哈喽&#xff0c;大家好呀&#xff01;这里是码农后端。完成了域名的备案与解析后&#xff0c;就可以通过域名来访问我们的网站了。本篇将介绍如何为我们的网站部署SSL安全证书&#xff0c;实现网站的 HTTPS 加密协议访问。 1、购买SSL证书 未进行SSL证书部署&#xff0c;访问网…

回答篇二:测试开发高频面试题目

引用之前文章&#xff1a;测试开发高频面试题目 本篇文章是回答篇&#xff08;持续更新中&#xff09; 1. 在测试开发中使用哪些自动化测试工具和框架&#xff1f;介绍一下你对其中一个工具或框架的经验。 a. 测试中经常是用的自动化测试工具和框架有Selenium、Pytest、Postman…

调整表格大小

方法一&#xff1a;使用鼠标拖动表格边框或右下角的调整控点 在Word文档中&#xff0c;选中要缩小的表格&#xff0c;将鼠标指针放在表格的边框线上&#xff0c;直到指针变成双箭头的形状。 按住鼠标左键&#xff0c;拖动边框线&#xff0c;调整表格的宽度或高度。如果同时按住…

AI视频教程下载:使用ChatGPT进行商务写作

你将学到什么&#xff1f; 学习如何将ChatGPT集成到你的写作过程中&#xff0c;并有效地将其用作商务写作的个人写作助手。 学习如何使用ChatGPT生成想法&#xff0c;提高你的书面沟通的结构、清晰度和连贯性。 你将学习使用ChatGPT的最佳实践&#xff0c;包括如何自定义其设…

Win10版本TDengine使用分享

软件介绍 TDengine是一款开源、高性能、可扩展的时间序列数据库&#xff08;TSDB&#xff09;。它由涛思数据公司开发&#xff0c;专为处理大规模时间序列数据而设计。时间序列数据是指按时间顺序排列的数据点序列&#xff0c;广泛应用于物联网、大数据分析、金融等领域。TDen…

Redis解决缓存一致性问题

文章目录 ☃️概述☃️数据库和缓存不一致采用什么方案☃️代码实现☃️其他 ☃️概述 由于我们的 缓存的数据源来自于数据库, 而数据库的 数据是会发生变化的, 因此,如果当数据库中 数据发生变化,而缓存却没有同步, 此时就会有 一致性问题存在, 其后果是: 用户使用缓存中的过…

DSP6657 GPIO中断学习

1 简介 使用创龙板卡的KEY2按键通过中断的方式控制LED3的亮灭 2 中断学习 在C665x设备上&#xff0c;CPU中断是通过C66x CorePac中断控制器进行配置的。该中断控制器允许最多128个系统事件被编程到任意12个CPU可屏蔽中断输入&#xff08;CPUINT4至CPUINT15&#xff09;、CPU…

短剧解说一键生成原创文案的快速方法

如今短剧创作火的一塌糊涂&#xff0c;它们以其简洁明了的剧情、生动有趣的角色和紧凑的节奏&#xff0c;吸引了大量观众的关注。因此&#xff0c;它所带来的流量是非常巨大&#xff0c;不少人将流量的获取瞄准了短剧创作领域以及短剧解说领域。而对于短剧解说人员来讲&#xf…

微服务项目收获和总结---第5天(定时发布)

延迟任务 目录 延迟任务技术对比&#xff1a; Redis实现定时任务&#xff1a;​编辑新增任务&#xff1a;取消任务&#xff1a;拉取任务&#xff1a;Zset定时刷新数据到List中&#xff1a;分布式锁实现定时任务只刷新一次&#xff1a; 技术对比&#xff1a; Redis实现定时任…

香橙派 AIpro 昇腾 Ascend C++ 分类模型适配

香橙派 AIpro 昇腾 Ascend C 分类模型适配 flyfish 文章目录 香橙派 AIpro 昇腾 Ascend C 分类模型适配前言一、PyTorch官网resnet模型处理方式1、PyTorch模型 导出 onnx格式2、完整测试 输出top1结果3、完整测试 输出top5结果 二、YOLOv8官网resnet模型Python处理方式三、昇腾…

云衔科技:为什么推荐使用zoho crm客户管理系统?

在当今快速变化的商业环境中&#xff0c;企业对高效、智能化的客户关系管理&#xff08;CRM&#xff09;系统的需求日益增长。Zoho CRM&#xff0c;作为全球领先的企业级CRM解决方案提供商&#xff0c;凭借其全面的功能、高度的可定制性、以及无缝集成的生态系统&#xff0c;成…

探寻导师:2024年最新研究生导师评价汇总

随着考研热潮的不断升温&#xff0c;对于研究生导师的选择变得愈发重要。导师不仅关系到研究生的学术成长&#xff0c;还直接影响到未来的职业发展。然而&#xff0c;如何找到一位合适的导师成为许多考生头疼的问题。为了帮助广大考生更好地选择导师&#xff0c;整理了最新最全…

Nature 正刊!瑞典于默奥大学研究团队在研究全球河流和溪流的甲烷排放中取得新进展

甲烷(CH4)是一种强有力的温室气体&#xff0c;自工业革命以来&#xff0c;其在大气中的浓度增加了两倍。有证据表明&#xff0c;全球变暖增加了淡水生态系统的 CH4 排放&#xff0c;为全球气候提供了积极的反馈。然而&#xff0c;对于河流和溪流来说&#xff0c;甲烷排放的控制…

区间类贪心,蓝桥云课 打折

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 0打折 - 蓝桥云课 (lanqiao.cn) 二、解题报告 1、思路分析 思路很简单&am…

c++(五)

c&#xff08;五&#xff09; 继承基类和派生类继承的格式继承的方式三种:public、private、protected 继承的规则多层继承多重继承 类与类的关系 继承 一个新类从已有的类那里获得其已有特性(属性、行为)&#xff0c;这种现象称为类的继承 基类和派生类 <1>从已有的类…

WPS PPT学习笔记 2 结构页的制作

制作PPT结构页 制作封面页、目录页、封底页。它们都属于结构页。而时间轴页&#xff0c;流程图页&#xff0c;框架图页这些属于内容页。 做一份PPT 讲一个故事 封面页 开头&#xff0c; 目录页 脉络&#xff0c; 各式内容页 详情&#xff0c; 封底页 结尾。 所有的结构页…

关于Windows中桌面窗口管理器的知识,看这篇文章就可以了

序言 你打开了任务管理器,发现了一个叫做“桌面窗口管理器”的东西,它是恶意软件吗?它应该在任务管理器吗?如果它应该在那里,它的作用什么?以下是你需要了解的所有信息。 什么是桌面窗口管理器 Desktop Window Manager(dwm.exe)是一个合成窗口管理器,可以在Windows…