datatable的数据进行组内排序_排序算法学习分享(四)希尔排序

bd1eeb2e0a30836c92dcbe6b0194a83e.png

排序,也称为排序算法,可以说是我们学习算法的过程中遇到的第一个门槛,也是实际应用中使用得较为频繁的算法,我将自己对所学的排序算法进行一个归纳总结与分享,如有错误,欢迎指正!

排序算法学习分享(一)选择排序

排序算法学习分享(二)交换排序---冒泡排序与快速排序

排序算法学习分享(三)插入排序

(一)排序的分类

排序算法主要分为内部排序与外部排序,当数据量大时,数据无法全部加载到内存中,因此需要接抓外部存储(文件、磁盘等)进行排序。而内部排序则是指将要处理的所有数据加载到内部存储器中,并在内存中就完成排序。

3dfee53c79897abe9bd9036d535c9dc5.png

本文针对的为内部排序。

(二)内部排序

4 希尔排序

前文我介绍了插入排序,但是插入排序会出现一个问题。如果我们拿到的是一个较小的数进行插入排序,那么元素后移的次数会明显增加,那么就会严重影响整个排序的效率。

接下来介绍的希尔排序就是经典的对插入排序的一种优化。

希尔排序,也称递减增量排序,是插入排序的一种更高效的改进版本。我们都知道,插入排序对已经有序的或者是有序程度高的序列排序是非常快的,但一般情况下,由于插入排序每插入一个元素都只能一个一个元素地进行移动,因此它的效率是十分低下的。

显然要优化插入排序的移动是很困难的,而希尔排序取巧地不去优化它的移动,希尔排序的思想我用一句话去概括:尽可能的在数组进行下一轮的排序时,提高数组的有序程度。

先记住一点:在序列的排序中,元素越少,需要交换的次数越少,排序越快。

那么怎么去提高一个数组的有序程度呢?用一个很有趣的东西——增量

这类似于分治思想,但它又不是。希尔排序利用增量这一个东西去将序列分割成若干个子序列,再将每个子序列分别排好。 那么究竟什么是增量?又要怎么利用增量?

增量就是一个等差数列的差值,比如1,3,5,7,9。它们的增量是2。一开始尽可能使用一个大的增量,使得每个子序列中的元素少,比如第一轮就尽量使得一个子序列的元素只有两个。

增量越大,那么分的组就会越多,每个组中的元素数目就会小。每一轮都比上一轮的增量按照一定的规律递减,那么分的组就会比上一轮的分的组少,而每个组中的元素就要比上一轮的元素要多,当增量一直减到1的时候,我们就会发现只有一个组了,而这个组中的元素就是整个序列的所有元素,这就是递减增量。

利用增量这样子分割序列是为了什么呢?是为了使下一轮的有序程度变高。为什么我说希尔排序是一种取巧呢?就是因为它耍赖皮,有序程度低的时候,增量就大,分组就多,组内元素就少,排序就快。当这一轮排序完成的时候,全体序列的有序程度一定是要比上一轮的有序程度要高的(有一些特殊情况,严谨地应该说是不低于)。

增量每一次发生递减,那么序列的有序程度就提高了那么一点,当增量递减到1的时候,序列的有序程度就已经很高的,这时再进行一轮插入排序,就很快了。

这么将还是有些抽象,我们举一个实例,上一些图来说明。

b4cfce7456a03ed1a03a463a0ce61641.png

这是一个原始数组,可以看到它的有序程度并不高。

我们对它进行第一次增量分组,使得每组中的元素尽可能少。最少的话是一个元素一个组,但是如果组中只有一个元素,那么组内的排序根本没有意义,因此第一次的这个尽可能少,就是两两一组。此时的增量为4。

5d7e6f060b125f94c4fbb69428815ac3.png

我们对每个子数组内进行排序。由于每个子数组内的元素很少,因此排序很快,排序完如下:

bd8cb3dfdde6612945a24a47a2f98f2f.png

我们已经可以看到只是经过简单的几个交换后数组的有序程度就已经显著提升了,那么接下来就是进入到下一轮。

递减增量,直接使增量减半(希尔增量),新的增量为4 / 2 = 2,将2作为新的增量重新进行分组,分组如下。

d358782e8cdf59e6482fa2acadb747e1.png

我们对每个分组内进行排序,因为经过了上一轮的排序,可以看到每个组内的有序程度比上一轮如果也按照这个增量分组的有序程度要高。

这就达到了希尔排序的目的,就是每一轮都要比上一轮的有序程度要高,这很像我们做产品时候的不断迭代。

排序好后如下:

49a6e0486c5ed98c1f5058da2ee7f25f.png

这一轮结束后增量再递减就变成1了,最后再进行一轮插入排序即可,此时需要移动的数仅仅就是5和3,8和9。有序程度比原数组高到不知道哪里去了。再来一轮插入排序就完成啦!

96066f4928183cb753344073947a41d2.png

其实递减增量的规则有很多种,不止折半这一种,有时候根据需求改变递减增量的方式会取得更优的性能。

下面尝试用代码实现希尔排序:

f2531e6d126db780794959dbf89d18d6.png

希尔排序使用的增量是折半的方式递减的,这种方式的增量叫做希尔增量。希尔排序利用增量分组粗调一般情况下是减少了插入排序的工作量,使得插入排序的时间复杂度低于O(n²)。

但是,在一种极端的情况下,希尔排序所做的粗略调整不但没有减少插入排序的工作量,反而增大的插入排序的工作量。

举一个例子:

645966506065f352ec8e2fdb57cad7df.png

我们利用希尔增量来分组,当增量为4时,分组为:(2,7),(1,6),(5,9),(3,8)。我们可以看到它在组内是有序的,再折半减少增量为2,分组为(2,5,7,9),(1,3,6,8),还是有序的,经过两轮增量排序,它的有序程度并没有提高,比起直接插入排序反而还增加分组排序的这一个步骤,增加了工作量。

会出现这种情况的原因在于希尔增量,希尔增量之间是等比的,这代表着等比之间是可以出现一定的盲区的,就像上面这个例子,就完美地处在了希尔增量之间的盲区。

那么才能使得增量之间没有盲区呢?最好的方式就是使得每一轮彼此的增量“互质”。而增量的方式很多,最为典型的就是Hibbard增量和Sedgewick增量。因为本文讲的是希尔排序,就不继续往下介绍了。

希尔排序是一个不稳定的排序算法,是因为在分组的过程中,两个元素的交换的跨度有时候是会很大的。比如m > i = j > k,而原数组是( i ,j ,k ,m ),那么第一轮希尔排序后,i 就到 j 后面了。

希尔排序的介绍就到这里啦!希尔排序的中心思想就是: 尽可能的在数组进行下一轮的排序前,提高数组的有序程度。即每一轮都比上一轮时候的有序程度要高。

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

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

相关文章

jupyter notebook 安装代码提示功能

效果 安装成功后,输入部分代码,按 tab 键,会提示代码 安装步骤 1.安装nbextensions 从国内的pip镜像下载快 pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com jupyter_contrib_nbextensions jupyter contr…

python需要配置环境变量吗_python为什么会环境变量设置不成功

学习python编程,首先要配置好环境变量。本文主要讲解python的环境变量配置,在不同版本下如何安装 Windows 打开Python官方下载网站 https://www.python.org/downloads/release/python-370/ x86:表示是32位电脑 x86-64:表示是64位电脑 目前Python版本分为…

一维数组、二维数组、三维数组、四维数组、多维数组的理解

以图书馆来举例 一维数组是一条线 二维数组是一页纸 三维数组是一本书 四维数组是书架 五维数组是图书室2201(好几个书架) 六维数组是图书馆某一层,2楼/3楼,好几个图书室 七维数组是整个图书馆 第N维数组是宇宙..................…

在资源使用状况视图中查看资源的负荷情况

只有工时类资源才会出现过度分配,因为工时类资源通常指组织内部的人力资源或者机械设备等,这些资源通常都有数量上的瓶颈,也只有工时类资源才会在【资源工作表】中设置它的最大单位和资源可用性,这就限制了它在不同时间段内的可用…

python常用单词自由且开放_python常用英语单词词汇 unit7

1. Darcula IntelliJ IDEA自带的黑色主题名称,Android Studio是基于IntelliJ IDEA的。 2. Appearance /prns/ n. 外观; 3. Custom /kstm/ n. 习惯; 4. UI abbr. 用户界面(user interface) 5.Terminate /tmnet/ 终止、结…

2018.10.29-2018.11.4

简述osi七层模型和TCP/IP五层模型应用层OSI 参考模型中最靠近用户的一层,是为计算用户提供应用接口,也为用户直接提供网络服务。常见的应用层网络服务协议有:HTTP,HTTPS,FTP,POP3,SMTP等表示层表示提供各种用于应用层数据编码和转换功能&…

CSV文件转Excel后数字自动转换成科学计数法的解决方法

CSV文件用Excel打开后,长度超过11位的数字自动转换成科学计数法显示,末尾数字变成“0000”,如何解决这一问题? 以“老劳模系统数据.CSV”为例,身份证码是科学计数法了 第一步:新建excel,用 off…

python 小说 云_python小说网站

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! python爬虫之小说网站--下载小说(正则表达式)思路:1. 找到要下载的小说首页,打开网页源代码进行分析(例:htt…

6.6(java学习笔记)文件分割(IO综合例子)

基本思路: 文件分割:将一个文件分割成若干个独立的文件。 设置分割后小文件文件的字节数,然后读取被分割文件, 将对应的字节数写入分割后的小文件中。 使用seek定位下一次读取位置。 文件合并:将分割后的若干的文件合并…

小米MIUI关闭内容中心通知

被MIUI的内容中心打扰了许久,终于找到彻底关闭它的方式。 这个内容中心,在应用列表里找不到卸载,在通知管理里也找不到,小米把它藏得深。 关闭内容中心通知 第一步,先进入内容中心,然后切换到后台&#…

Java虚拟机-第二篇-GC算法与内存分配策略

2019独角兽企业重金招聘Python工程师标准>>> GC引入 在Java的运行时数据区中,程序计数器、虚拟机栈、本地方法栈三个区域都是线程私有的,随线程而生,随线程而灭,在方法结束或线程结束时,内存自然就跟着回收…

Caffe学习记录(十一) ICNet分割网络学习

ICNet 是一个既考虑性能,又考虑准确率的分割网络,包含了语义分割和边缘精确分割,因为偶然看到就简单的了解一下,记录下来 论文是: ICNet for Real_time Semantic Segmentation on High Resolution Images,整篇文章都在…

如何利用python自动化办公项目_python办公自动化:自动进行word文档处理和排版

上节python办公自动化:自动打开word文档我们一起学会了在python里打开并保存一个word文档。这节我们将会学会如何利用python进行文本处理和将其在word里进行排版等技巧。python进行文本处理和将其在word里进行排版等技巧 使用文本 要有效地处理文本,首先要了解一些块…

不同项目组织结构间的区别

项目组织结构分 职能型 项目型 矩阵型 弱矩阵型 平衡矩阵 强矩阵 职能型 场景举例: 去饭店吃饭。 饭店A,门口宣传接待一组人,进店了,换另一组人安排就坐点餐,过一会儿,有专人上菜...... 这是职能型&#x…

比较合理的项目组织架构

(从自己从业经验中总结所得) PMO就像是操作系统,项目组1...N就像进程(开启多个软件),项目任务就像线程,项目组成员就像CPU(具体干活的),CPU资源是有限的&…

小计 合计 总计 共计 怎么解释?

排列顺序:小计、总计、合计。共计分开使用。 小计:小计就是简单核算一下单个体,可理解为日小计 合计:合计就是把所有小计加起来,可理解为月合计 总计:总计就是把合计加起来,可理解为年总计 …

巧用位运算存状态

2019独角兽企业重金招聘Python工程师标准>>> 某种场景需要,一个事物 有多种状态并列存在的时候,或者权限,我们可以使用 |,&,~ 来处理,具体代码如下: package com.example.demo;/*** 权限状态处理*/ public class StatusUtil {/*** 判断状态是否开启* param fl…

python怎么做项目_听说你没有python项目可做,我教你个方法

原标题:听说你没有python项目可做,我教你个方法 学习了一段时间的Python,最近出现了“饥荒”,感觉需要多看些代码,多学习学习别人做些什么,但却不知道做点什么来进行练习。 说到看代码,我就想到…

Linux系统CPU相关信息查询

Linux系统CPU相关信息查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 一.lscpu常用参数介绍 1>.查看帮助信息 [rootnode105 ~]# lscpu -h-a, –all: 包含上线和下线的cpu的数量,此选项只能与选…

excel下拉让函数参数部分不变

原理 使用相对引用就会变,bai使用绝对引用du就不变 A1是相对引用,上下拉公式的时候会zhi变成A2,A3…… $A$1是行列绝对引用dao,上下拉公式的时候不会变化 $A1,是行绝对引用,上下拉公式的时候会变化,$A2&am…