数据结构与算法-排序(七)希尔排序(Shell Sort)
摘要
看希尔排序需要先想象出一个二维的矩阵,在这个矩阵中,有多少列数据全看步长(一定的规则得到)。处理完之后,就再接着用另一个步长组成矩阵处理。直到步长全部使用完。
这里的巧妙之处就是没有把序列先处理成二维数组,而是通过与步长配合,依旧在一维的序列中处理。
逻辑
希尔排序相当于把序列当作一个矩阵,逐列进行排序。当全部排序完成,整个序列就完全有序
矩阵的列数取决于步长序列
流程
- 创建步长序列
- 从最大步长开始,整列排序,直到排序完成
实现
创建步长序列,这里是有一个数组存放步长数据。步长是序列的长度减半直到步长为0 结束。这里必定会有步长是 1 的数据,所以不用担心序列没有完全排序完。
List<Integer> shellStepSequence() {
List<Integer> stepSequence = new ArrayList<>();
int step = array.length;
while ((step >>= 1) > 0) {
stepSequence.add(step);
}
return stepSequence;
}
按照步长序列遍历,序列就会按照不同的步长去处理排序。然后通过不断地缩小步长来使得序列逐渐成为一维的序列。
List<Integer> stepSequence = shellStepSequence();
for (Integer step : stepSequence) {
sort(step);
}
把每一列进行排序。数组中的索引是 col+row*step
。这个地方就是巧妙的地方了,通过 col+row*step
来处理每一列中的元素比较排序处理。用这种方式就相当于把一个一维数组给拆分成每一行最多有 step 的元素的多列序列,即二维数组。
而这里的巧妙就是,给我们营造了一个二维序列的空间,实际的比较和交换逻辑还是在一维数组上进行,不用额外创造空间,这样的逻辑,真的是牛。
/*
* 分成 step 列进行排序
*/
void sort(int step) {
// col: 第几列
for (int col = 0; col < step; col++) {
// 对第 col 列进行排序
// 对 [0, array.length) 进行插入排序
for (int begin = col + step; begin < array.length; begin+=step) {
int cur = begin;
while (cur > col && cmp(cur, cur - step) < 0) {
swap(cur, cur - step);
cur -= step;
}
}
}
}
时间和空间复杂度
- 最好、平均时间复杂度:O(1)
- 最坏时间复杂度:O(n^2)
- 空间复杂度:O(1)
- 属于不稳定排序
数据结构与算法-排序(七)希尔排序(Shell Sort)的更多相关文章
- Hark的数据结构与算法练习之希尔排序
算法说明 希尔排序是插入排序的优化版. 插入排序的最坏时间复杂度是O(n2),但如果要排序的数组是一个几乎有序的数列,那么会降低有效的减低时间复杂度. 希尔排序的目的就是通过一个increment(增 ...
- 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现
内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...
- Python数据结构与算法(几种排序)
数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...
- 《Algorithm算法》笔记:元素排序(2)——希尔排序
<Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...
- 数据结构和算法(Golang实现)(18)排序算法-前言
排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...
- 数据结构和算法(Golang实现)(19)排序算法-冒泡排序
冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...
- 数据结构和算法(Golang实现)(21)排序算法-插入排序
插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑 ...
随机推荐
- Nginx-多服务绑定80端口及映射域名
多服务绑定80端口及映射域名 说明:业务需要配置的样例模板,如需深入了解,请查看官方文档 1.Nginx配置文件nginx.conf(可拆分多台机器部署) worker_processes 1; e ...
- 在docker中使用nginx部署前端项目
前言 部署了三个nginx用于前端项目, 并使用keepalived部署好热备, 所以总共有5个nginx 创建好nginx的文件和配置 根据上面的指令创建好目录 mkdir /home/web/ng ...
- java实现遍历文件目录,根据文件最后的修改时间排序,并将文件全路径存入List集合
package com.ultra.aliyun.control.main; import java.io.File; import java.util.ArrayList; import java. ...
- leetcode 面试题 17.22. 单词转换(DFS+回溯)
题目描述 思路分析 这题回溯,先想出它的空间解是什么,这里空间解,其实就是给的原字符串到结束字符串中间的变形过程,那么就可以容易的画出一个解空间树,用深度搜索进行搜索, 剪枝后,进入下一个维度,再进行 ...
- Jmeter监控服务器CPU,Memory,Disk,Network性能指标
本文主要说一下如何通过JMeter插件来监控服务器CPU.内存.磁盘.网络等相关资源. 一.下载 第一种方案: 首先进入网址https://jmeter-plugins.org/downloads/o ...
- Anaconda软件安装使用问题
目录 更新源 用conda安装包出现的环境不一致问题 更新源 命令行 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/ ...
- Python单元测试框架unittest之单用例管理(一)
一.概述 本文介绍python的单元测试框架unittest,unittest原名为PyUnit,是由java的JUnit衍生而来,这是Python自带的标准模块unittest.unittest是基 ...
- 「CF559E」 Gerald and Path
「CF559E」 Gerald and Path 为啥我现在做啥题都在想网络流啊 考虑 \(\texttt{DP}\). 容易想到状态应该包含当前枚举了前 \(i\) 条线段,且第 \(i\) 条线段 ...
- File类与常用IO流第五章——IO字符流
字符流,只能操作文本文件,不能操作图片.视频等非文本文件 字符输入流 java.io.Reader 字符输入流中一些共性的成员方法 int read():读取单个字符并返回. int read(cha ...
- 【动态规划】石子合并 luogu-1880
分析 简单的区间DP AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeo ...