【排序算法】—— 希尔排序

目录

一、希尔排序原理

二、希尔排序的思路

三、希尔排序为什么快

四、如何取增量

五、源码


        希尔排序是简单插入排序的一种升级版,它也是用了插入的思想,而插入排序相比冒泡排序和选择排序的效率要高的多,再将它优化为希尔排序后效率跟原来根本就不在一个级别。接下来我们就一起来学习一下希尔排序

一、希尔排序原理

        希尔排序的原理是插入排序,接下来先讲一下简单插入排序

简单插入排序原理:

        首先假设第一个元素就是一个小数组并且是有序的,然后把第二个元素当做新加入的元素,依次往前遍历把它放在合适的位置保持小数组有序,同理把第三个元素当做新加入的元素,依次往前遍历把它放在合适的位置保持前面的小数组有序,依次重复下去直到把大数组的最后一个元素给放置好,这有点像高等代数里的基底扩充定理,从一个小的空间覆盖到整个大的空间。

动态图:

//简单插入排序
void InsertSort(int* a, int sz)
{for (int i = 0; i < sz - 1; i++){int j = i, tmp = a[i + 1];while (j >= 0 && tmp < a[j]){a[j + 1] = a[j--];}a[j + 1] = tmp;}
}

        如果一个数组储存数据是顺序有序的时候效率是最高的时间复杂度为O(n)

        有的时候该排序遇到一些极端的情况还是比较低效的,比如需要将一组数组进行升序排序,如果这组数据恰好是降序(即逆有序)的话就会很麻烦时间复杂度O(N^2),它需要将新元素前面的所有数据都遍历完。为了解决类似的问题就引入了希尔排序。

二、希尔排序的思路

        希尔排序的原理还是插入排序,就是在做简单插入排序之前做一下预处排序,

        先把数据分组,如上图分为(1),(2),(3)三组,然后分别对这三组进行简单插入排序,这是一次预排序。

        那么这三组是如何分出来的呢?主要是涉及到一个增量的问题,如上图的增量是3,在取第(1)组元素时每隔3个元素取一次,第(2)第(3)组同样,直到把每个元素都取到。

       排完上面三组后继续减小增量分组进行简单插入排序,比如排完以3为增量的三组后,再把增量变为2分为二组,最后当增量为1的时候相当于对整个大组做了一个简单插入排序,排完这一趟后这个数组就有序了,希尔排序结束。

三、希尔排序为什么快

        简单插入排序的时间复杂度为O(N^2),而希尔排序的时间复杂度大概为O(N^1.3),当然这还与如何取增量有关。 

        希尔排序确实比之前的简单插入排序所排的组数要多,因为简单插入排序相当于只排了一组,那么它为什么还那么快呢? 

        因为它大大的减少了数据挪动次数,在做预排序的时候它是以增量的跨度去挪动的,这就使一个数据更快的接近它的准确位置(也就是排序后它该在的位置)。

四、如何取增量

        希尔排序的核心就在于通过设定不同的增量序列来优化插入排序的性能。增量序列的选择对排序速度有显著影响。一般来说,增量序列的选择涉及多种策略,而最佳的增量序列并没有一个固定的标准。比较常用效果比较好的增量设定为size/3+1。size为数组长度。

五、源码

#include<stdio.h>
//单组排
void ShellSort1(int* a, int sz)//(一组排完再排另一组)
{int gap = sz;//增量while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < gap; i++){for (int j = i; j < sz - gap; j += gap){int m = j;int tmp = a[j + gap];while (m >= 0 && tmp < a[m]){a[m + gap] = a[m];m -= gap;}a[m + gap] = tmp;}}}
}
//多组一起排
void ShellSort2(int* a, int sz)
{int gap = sz;//增量while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < sz - gap; i++){int j = i;int tmp = a[i + gap];while (j >= 0 && tmp < a[j]){a[j + gap] = a[j];j -= gap;}a[j + gap] = tmp;}}
}
int main()
{int arr[] = { 8,3,4,9,2,6,5,7,1,10 };int size = sizeof(arr) / sizeof(int);ShellSort1(arr, size);for (int i = 0; i < size; i++)printf("%d ", arr[i]);return 0;
}

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

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

相关文章

51单片机STC89C52RC——12.1 数据存储芯片AT24C02

目的/效果 利用存储芯片AT24C02存储数据&#xff0c;LCD1602显示存储的数据。 一&#xff0c;STC单片机模块 二&#xff0c;AT24C02存储芯片 2.1 介绍 AT24C02是一个2K位串行CMOS E2PROM&#xff0c;内部含有256个8位字节&#xff0c;采用先进CMOS技术实质上减少了器件的功…

通讯录管理系统——查找联系人

功能描述&#xff1a;按照姓名查看指定联系人的信息 查看联系人实现步骤 1.封装查找联系人函数 2.测试查找指定联系人 一、封装查找联系人函数 实现思路&#xff1a;判断用户指定的联系人是否存在&#xff0c;如果存在&#xff0c;显示信息&#xff0c;不存在提示查无此人…

如何在FastAPI服务器中添加黑名单和白名单实现IP访问控制

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 添加黑名单功能步骤1:安装依赖步骤2:创建FastAPI应用步骤3:添加黑名单📝 添加白名单功能步骤1:创建白名单列表步骤2:添加白名单检查⚓️ 相关链接 ⚓️📖 介绍 📖 在现代网络应用开发中,为了增强…

C++【引用】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

进程间通信简介-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

进程间通信简介 进程间通信简介 进程间进程简称IPC(interprocess communication)&#xff0c;进程间通信就是在不同进程之间传递信息或交换信息 进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的…

武汉星起航:一站式服务,助力亚马逊卖家高效运营,实现收益飞跃

在跨境电商的浪潮中&#xff0c;武汉星起航电子商务有限公司以其独特的一站式跨境电商服务&#xff0c;为众多亚马逊卖家提供了强有力的支持&#xff0c;助力他们在不断发展的市场中脱颖而出&#xff0c;实现收益的大幅提升。 武汉星起航的一站式跨境电商服务&#xff0c;以其…

JAVA医院绩效考核系统源码:三级公立医院绩效考核系统源码 可源码交付,支持二开

JAVA医院绩效考核系统源码&#xff1a;三级公立医院绩效考核系统源码 可源码交付&#xff0c;支持二开 医院绩效考核系统是一个集数据采集、分析、评估、反馈于一体的信息化工具&#xff0c;旨在提高医疗服务质量、优化资源配置、促进医院可持续发展。以下是对医院绩效考核系统…

API接口知识小结

应用程序接口API&#xff08;Application Programming Interface&#xff09;&#xff0c;是提供特定业务输出能力、连接不同系统的一种约定。这里包括外部系统与提供服务的系统&#xff08;中后台系统&#xff09;或后台不同系统之间的交互点。包括外部接口、内部接口&#xf…

Java访问修饰符的区别

public&#xff1a;公开的&#xff0c;任何地方都可以访问。 protected&#xff1a;受保护的&#xff0c;同一个包中的类和所有子类(可跨包)可以访问。 private&#xff1a;私有的&#xff0c;只有在同一个类中可以访问。 默认&#xff08;无修饰符&#xff09;&#xff1a;包级…

ORBSLAM3_ROS_Ubuntu18_04环境搭建安装

orbslam3安装 ORB-SLAM3配置及安装教程&#xff08;2023.3&#xff09;_orbslam3安装-CSDN博客 换源&#xff0c;换成国内的 搜索software 安装工具 sudo apt install git sudo apt update sudo apt install gcc g cmake安装 cmake安装新版本 ubuntu20.04安装cmake详细…

转让无区域商业管理公司基本流程和要求

无区域公司转让的条件和要求取决于您的业务需求和目标。我们的专业团队将与您合作&#xff0c;深入了解您的公司背景、行业情况和发展计划&#xff0c;为您量身定制适合您的转让方案。无论是公司规模、经营期限、资产状况还是法律形式&#xff0c;我们都将综合考虑确保达到您的…

一键掌控,文件格式转换无忧!轻松驾驭各种文件格式,高效管理您的数字世界

信息爆炸的时代&#xff0c;我们每天都会接触到各种各样的文件格式。无论是工作文档、图片、视频还是音频文件&#xff0c;它们都以不同的格式存在于我们的电脑和移动设备中。然而&#xff0c;不同的软件和应用往往只支持特定的文件格式&#xff0c;这给我们的工作和生活带来了…

数据结构历年考研真题对应知识点(树的基本概念)

目录 5.1树的基本概念 5.1.2基本术语 【森林中树的数量、边数和结点数的关系&#xff08;2016&#xff09;】 5.1.3树的性质 【树中结点数和度数的关系的应用&#xff08;2010、2016&#xff09;】 【指定结点数的三叉树的最小高度分析&#xff08;2022&#xff09;】 5.1…

[软件安装]Dev C++

一、下载Dev C软件安装包 1、官网下载官网 2、百度网盘下载压缩包 二、安装Dev C 1、解压Dev C软件安装包 2、找到【Dev-Cpp 5.11…】应用程序&#xff0c;右键选择【以管理员身份运行】它 3、设置语言 回到桌面&#xff0c;右键桌面上的【Dev C 5.11软件图标】&#xff0c…

什么是DEQ?

DEQ (Delivered Ex Quay, Duty Paid) 是指目的港码头交货 (……指定目的港)。 这种术语规定卖方在指定目的港码头将货物交给买方处置&#xff0c;并且不办理进口清关手续。 DEQ适用范围 DEQ术语仅适用于海运、内河运输或多式联运&#xff0c;并且在目的港码头卸货时使用。如…

探索人工智能和LLM对未来就业的影响

近年来&#xff0c;人工智能&#xff08;AI&#xff09;迅猛发展&#xff0c;引发了人们的兴奋&#xff0c;同时也引发了人们对就业未来的担忧。大型语言模型&#xff08;LLM&#xff09;就是最新的例子。这些强大的人工智能子集经过大量文本数据的训练&#xff0c;以理解和生成…

Python 面试【初级】

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

安宝特方案 | AR术者培养:AR眼镜如何帮助医生从“看”到“做”?

每一种新药品的上市都需要通过大量的临床试验&#xff0c;而每一种新的手术工具在普及使用之前也需要经过反复的实践和验证。医疗器械公司都面临着这样的挑战&#xff1a;如何促使保守谨慎的医生从仅仅观察新工具在手术中的应用&#xff0c;转变为在实际手术中实操这项工具。安…

011、MongoDB副本集数据同步机制深度解析

目录 MongoDB副本集数据同步机制深度解析 1. 副本集架构概述 1.1 基本组成 1.2 节点角色 2. 数据同步过程详解 2.1 初始同步 2.2 持续复制 2.3 Oplog详解 3. 数据一致性与可用性 3.1 写关注(Write Concern) 3.2 读偏好(Read Preference) 3.3 因果一致性会话 4. 高…

IBCS 虚拟专线——企业网络困境的破局者

企业对于高效、稳定且成本合理的网络解决方案的需求愈发迫切。作为一家企业的技术负责人&#xff0c;我曾深陷于企业网络的种种困境之中&#xff0c;直到 IBCS 虚拟专线的出现&#xff0c;为我们带来了转机。 我们的企业在发展过程中&#xff0c;面临着诸多网络相关的挑战。随…