排序——希尔排序

news/发布时间2024/9/20 5:53:08

希尔排序

希尔排序步骤

        希尔排序的核心还是插入排序,但是把插入排序分成两部分,1.预排序2.插入排序。先对原数组进行预排序,使数组接近有序(让更大的数字和更小的数字更快的分配到两边),然后再对已经接近有序的数组进行插入排序,这样就会快很多。

        时间复杂度约为:O(N^1.3);空间复杂度O(1);由于希尔排序有分预排序,所以有可能对相同大小的数字会改变他们的相对位置,是不稳定排序

        预排序:把原数组分组,然后对不同的分组进行插入排序,例如下面这串逆序的数字,我们对其分组分为3组,先进行预排序,让数组接近有序。

        不断地进行预排序,直到我们取的gap=1(gap表示同组数据之间的间距),就是直接插入排序,这样我们就很好的优化了直接插入排序的时间复杂度,希尔排序就是直接插入排序的进阶版。

        我们用gap表示一组的间隔,这样总共就有gap组(上述案例gap=3)。当gap过大时,较大的大的数和较小的数就能更快地跳到两边,但是相对的,一次gap排完后数组也更不接近有序;当gap过小时,就约等于直接插入排序,遇到数据过多时,希尔排序就失去了原本的意义。所以一般先给gap赋值n(总数)再取gap=gap/2或者gap=gap/3+1(gap除2的最后一次gap一定是1,gap除3的最后一次可能会是0,为了让最后一次gap一定为1,所以再+1),这样就刚好达到了一个平衡。(gap=1就是直接插入排序)

        总结:希尔排序核心还是是直接插入排序,差别在于直接插入排序就是gap=1,而希尔排序是gap从n/2或者n/3+1开始不断地趋于1,最终gap=1进行一次直接插入排序就完成了。但希尔排序内部还有不同写法,下述为希尔排序的两种写法。

希尔排序写法

单组排序:

        排完一组再重新返回起点,再后移一位排下一组,总共排gap组。

多组并排:

        每次排序完后往后移动一位,排下一组,当向后移gap位后又重新排第一组。即i=0时是一组,i++后又是一组,间隔是gap,(i=0和i+=gap是同一组

计算希尔排序时间复杂度

        我们先假设n(总数)很大,外面的时间复杂度就为log3n,接着计算内部预排序的时间复杂度。由于n很大,那么第一次gap=n/3+1也会很大,我们忽略后面的+1,这样相当于有n/3组,每组有3个元素,当逆序情况时,每组要移动1+2=3次,那么累计的次数就是n/3*3=n。

        然后gap在除3,gap=gap/3+1,我们在忽略+1,就得到了gap=n/9,相当于分成了n/9组,每组要移动(1+2+3+...+8)=36次,再当当前数据还是逆序,那么累计次数为n/9*36=4n,看起来是变大了的,但实际上因为我们移动过了原逆序数据,第二次移动时肯定不为完全逆序,次数肯定会减少。

        这样一直减小gap,知道gap=1时,就是直接插入排序,这时由于我们的数据经过上述预排序后已经变得非常接近有序了,所以累计次数就相当于n(走一遍数组,调一小部分),总时间复杂度就为上述累计次数相加,时间复杂度大约为O(N^1.3)

希尔排序代码

 单组排序:

//希尔排序
void ShellSort(int *arr, int n)
{int gap = n;//重新上来时gap=1就说明上次排序是直接插入排序while (gap > 1){//gao有两种取法:如下//gap = gap / 2;gap = gap / 3 + 1;//单组排序//一组一组排序,排完一组再排下一组,总共排gap组for (int j = 0; j < gap; j++){//每组下标i+=gap,向后移gap位for (int i = 0; i < n - gap; i += gap){//直接插入int end = i;int tmp = arr[end + gap];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];end -= gap;}elsebreak;}arr[end + gap] = tmp;}}}
}

多组并排:

//希尔排序
void ShellSort(int *arr, int n)
{int gap = n;//重新上来时gap=1就说明上次排序是直接插入排序while (gap > 1){//gao有两种取法:如下//gap = gap / 2;gap = gap / 3 + 1;//多组并排,i=0时是一组,i++后又是一组,间隔是gap,(i=0和i+=gap是同一组)for (int i = 0; i < n - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];end -= gap;}elsebreak;}arr[end + gap] = tmp;}}
}

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

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

相关文章

模拟算法题练习(二)(DNA序列修正、无尽的石头)

目录 &#xff08;一、DNA序列修正&#xff09; 问题分析 方法实现 时间复杂度和空间复杂度分析 &#xff08;二、无尽的石头&#xff09; &#xff08;一、DNA序列修正&#xff09; 问题描述 在生物学中&#xff0c;DNA序列的相似性常被用来研究物种间的亲缘关系。现在我…

MySQL深入——22

kill不掉的语句 在MySQL当中有两个kill命令一个是kill query 线程id表示中止这个线程当中正在执行的语句&#xff0c;另外一个是 kill Connection线程id表示断开这个连接。 在使用MySQL时&#xff0c;使用kill命令之后看show processlist显示的command列为killed&#xff0c;…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-34-处理https 安全问题或者非信任站点-下篇

1.简介 这一篇宏哥主要介绍playwright如何在IE、Chrome和Firefox三个浏览器上处理不信任证书的情况&#xff0c;我们知道&#xff0c;有些网站打开是弹窗&#xff0c;SSL证书不可信任&#xff0c;但是你可以点击高级选项&#xff0c;继续打开不安全的链接。举例来说&#xff0c…

自动化测试摸索:python+selenium+pytest(持续更新.....)

一、环境搭建 1、python 安装 下载链接&#xff1a;Python Releases for Windows | Python.org 自己选择合适的版本下载 当下载完毕时&#xff0c;找到该安装程序&#xff1a;python-3.12.2-amd64.exe文件&#xff0c;双击启动安装向导。 为了防止C:盘文件因系统故障或者无…

CDN原理探究

来源于百度&#xff1a; https://baike.baidu.com/item/%E5%86%85%E5%AE%B9%E5%88%86%E5%8F%91%E7%BD%91%E7%BB%9C/4034265?frge_ala 通过上图&#xff0c;我们可以了解到&#xff0c;使用了CDN缓存后的网站的访问过程变为&#xff1a; 用户向浏览器提供要访问的域名&#xff…

unsigned详讲(干货满满)

前言&#xff1a;过年偷懒了(●ˇ∀ˇ●)&#xff0c;但是年后开学了一定要恢复学习状态&#xff0c;在复习加继续学习的途中&#xff0c;我发现对于unsigned关键字的掌握并不是很熟练&#xff0c;于是翻阅了各个大佬的博客以及书籍&#xff0c;总结了对于unsigned的一些知识点…

pip降级在pycharm中

PyCharm依赖于"–build-dir"参数安装第三方库&#xff0c;但该参数在最新的23.0版pip中已删除 解决办法就是降级pip&#xff0c;PyCharm中选择File&#xff0c;找到编译器&#xff0c;点击pip&#xff0c;勾选对应版本即可 或者在cmd中执行运行python -m pip install…

大语言模型推理加速技术:计算加速篇

原文&#xff1a;大语言模型推理加速技术&#xff1a;计算加速篇 - 知乎 目录 简介 Transformer和Attention 瓶颈 优化目标 计算加速 计算侧优化 KVCache Kernel优化和算子融合 分布式推理 内存IO优化 Flash Attention Flash Decoding Continuous Batching Page…

Redis冲冲冲——事务支持,AOF和RDB持久化

目录 引出Redis事务支持&#xff0c;AOF和RDB持久化1、Redis的事务支持2、Redis的持久化 Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Redis冲冲冲——事务支持&#xff0c;AOF和RDB持久化 Redis事务支持&#xff0c;AOF和…

Mybatis批量更新对象数据的两种方法

说明&#xff1a;遇到一次需要批量修改对象的场景。传递一个对象集合&#xff0c;需要根据对象ID批量修改数据库数据&#xff0c;使用的是MyBatis框架。查了一些资料&#xff0c;总结出两种实现方式。 创建Demo 首先&#xff0c;创建一个简单的Demo&#xff1b; &#xff08…

K8S存储卷与PV,PVC

一、前言 Kubernetes&#xff08;K8s&#xff09;中的存储卷是用于在容器之间共享数据的一种机制。存储卷可以在多个Pod之间共享数据&#xff0c;并且可以保持数据的持久性&#xff0c;即使Pod被重新调度或者删除&#xff0c;数据也不会丢失。 Kubernetes支持多种类型的存储卷…

C/C++ 迷宫游戏

游戏介绍 这个迷宫探险游戏有以下功能&#xff1a; 探险&#xff1a;选择该选项后&#xff0c;玩家会进入地下迷宫进行探险。在随机事件中&#xff0c;可能会遇到陷阱、发现金币或者什么都没有发生。陷阱会使玩家失去一定的生命值&#xff0c;金币可以增加玩家的金币数量。 休…

C++——内存管理(new和delete)详解

目录 C/C内存管理 案例&#xff1a;变量在内存中到底会在哪&#xff1f; New和delete Operator new和operator delete函数 New和delete的原理 对内置类型 对自定义类型 定位new New/delete和malloc/free的区别 C/C内存管理 C/C内存管理分布图&#xff1a;&#xff08;从…

2024牛客寒假算法基础集训营4

目录 A.柠檬可乐 B.左右互博 C.冬眠 D.守恒 E.漂亮数组 F.来点每日一题 G.数三角形&#xff08;easy&#xff09; A.柠檬可乐 阅读理解题&#xff0c;依照题目直接模拟即可 void solve(){int a,b,k; cin>>a>>b>>k;if(a>k*b) cout<<"go…

【Java】基本数据类型、包装类与字符串间的转换 例题

写在前面&#xff1a; 关于这道题&#xff0c;初见感觉有点cpu烧坏了&#xff0c;准确来说是看了网上的一些讲解都感觉不尽人意。自己整理了一下&#xff0c;希望能帮助到大家。 题目&#xff1a; 如下两个题目输出结果相同吗&#xff1f;各是什么。 Object o1 true ? new…

Java毕业设计-基于springboot开发的Web社区医院管理服务系统-毕业论文+答辩PPT(有源代码)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、管理员功能模块3、用户功能模块4、医生功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发…

CGI程序与ShellShock漏洞

CGI是什么&#xff1f; CGI&#xff08;通用网关接口&#xff0c;Common Gateway Interface&#xff09;程序是一种用于在Web服务器上执行动态内容的技术。与服务器上普通的后端代码相比&#xff0c;CGI程序有几个区别&#xff1a; 执行环境&#xff1a; CGI程序在服务器上作为…

从CPU缓存结构到原子操作

一、CPU缓存结构 1.1 CPU的多级缓存 因为CPU的计算速度非常快&#xff0c;但内存的访问速度相对较慢。因此&#xff0c;如果CPU每次都要从内存读取数据&#xff0c;会造成大量的等待时间&#xff0c;降低整体性能。 通过引入多级缓存&#xff0c;可以在CPU和内存之间建立数据…

3月1号代码随想录二叉搜索树中的插入操作

301.二叉搜索树中的插入操作 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;…

html样式排版

<template><div class"box"><div class"header">头部</div><div class"main"><div class"left">菜单</div><div class"right"><div class"right-contentr"&g…
推荐文章