摘要

看希尔排序需要先想象出一个二维的矩阵,在这个矩阵中,有多少列数据全看步长(一定的规则得到)。处理完之后,就再接着用另一个步长组成矩阵处理。直到步长全部使用完。

这里的巧妙之处就是没有把序列先处理成二维数组,而是通过与步长配合,依旧在一维的序列中处理。

逻辑

希尔排序相当于把序列当作一个矩阵,逐列进行排序。当全部排序完成,整个序列就完全有序

矩阵的列数取决于步长序列

流程

  1. 创建步长序列
  2. 从最大步长开始,整列排序,直到排序完成

实现

创建步长序列,这里是有一个数组存放步长数据。步长是序列的长度减半直到步长为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)的更多相关文章

  1. Hark的数据结构与算法练习之希尔排序

    算法说明 希尔排序是插入排序的优化版. 插入排序的最坏时间复杂度是O(n2),但如果要排序的数组是一个几乎有序的数列,那么会降低有效的减低时间复杂度. 希尔排序的目的就是通过一个increment(增 ...

  2. 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现

    内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...

  3. 数据结构和算法(Golang实现)(22)排序算法-希尔排序

    希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...

  4. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  5. 《Algorithm算法》笔记:元素排序(2)——希尔排序

    <Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...

  6. 数据结构和算法(Golang实现)(25)排序算法-快速排序

    快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...

  7. 数据结构和算法(Golang实现)(18)排序算法-前言

    排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...

  8. 数据结构和算法(Golang实现)(19)排序算法-冒泡排序

    冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...

  9. 数据结构和算法(Golang实现)(20)排序算法-选择排序

    选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...

  10. 数据结构和算法(Golang实现)(21)排序算法-插入排序

    插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑 ...

随机推荐

  1. 2020年MySQL数据库面试题总结(50道题含答案解析)

    1.MySQL 中有哪几种锁? (1)表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最 高,并发度最低. (2)行级锁:开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最 ...

  2. Laravel + Swoole 打造IM简易聊天室

    最近在学习Swoole,利用Swoole扩展让PHP生动了不少,本篇就来Swoole开发一款简易的IM聊天室 应用场景:实现简单的即时消息聊天室. (一)扩展安装 pecl install swool ...

  3. TestComplete 64位和32位之间的区别

    在64位系统上,有两种版本的TestComplete:32位和64位.本主题描述了TestComplete x64及其32位版本之间的区别.关于TestComplete x64启动TestComple ...

  4. 谈谈Java事务

    事务具基本特征(ACID) ① Atomi(原子性):事务中包含的操作被看做一个整,要么完全部成功,要么全部失败. ② Consistency(一致性):事务在完成时,必须是所有的数据都保持一致状态, ...

  5. Python 操作 MySQL 的5种方式

    不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的5种方式,你可以在实 ...

  6. 传统.NET 4.x应用容器化体验(1)

    我们都知道.NET Core应用可以跑在Docker上,那.NET Framework 4.x应用呢?借助阿里云ECS主机(Windows Server 2019 with Container版本), ...

  7. python 17篇 unittest单元测试框架

    单元测试:开发程序的人自己测试自己的代码 unittest自动化测试框架 1.单元测试 import unittest def add(a,b): return a+b # 在运行时不要用run un ...

  8. Linux小白基础命令操作

    [root@localhost ~]]# [当前登录系统的用户@主机名称 当前所在的目录]# #表示为管理员登录 $ 表示为普通用户登录 切换用户su 用户名     切换后所在目录不变  ,#变成$ ...

  9. 【LeetCode】12. 整数转罗马数字

    12. 整数转罗马数字 知识点:字符串 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 100 ...

  10. Pytest单元测试框架之parametrize参数化

    1.参数化的本质:相同的步骤,但测试数据不同,比如登录的场景 import mathimport pytest# 方式一:分离出Listdef list_Test(): list = [ [2, 2, ...