摘要

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

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

逻辑

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

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

流程

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

实现

创建步长序列,这里是有一个数组存放步长数据。步长是序列的长度减半直到步长为0 结束。这里必定会有步长是 1 的数据,所以不用担心序列没有完全排序完。

  1. List<Integer> shellStepSequence() {
  2. List<Integer> stepSequence = new ArrayList<>();
  3. int step = array.length;
  4. while ((step >>= 1) > 0) {
  5. stepSequence.add(step);
  6. }
  7. return stepSequence;
  8. }

按照步长序列遍历,序列就会按照不同的步长去处理排序。然后通过不断地缩小步长来使得序列逐渐成为一维的序列。

  1. List<Integer> stepSequence = shellStepSequence();
  2. for (Integer step : stepSequence) {
  3. sort(step);
  4. }

把每一列进行排序。数组中的索引是 col+row*step。这个地方就是巧妙的地方了,通过 col+row*step 来处理每一列中的元素比较排序处理。用这种方式就相当于把一个一维数组给拆分成每一行最多有 step 的元素的多列序列,即二维数组。

而这里的巧妙就是,给我们营造了一个二维序列的空间,实际的比较和交换逻辑还是在一维数组上进行,不用额外创造空间,这样的逻辑,真的是牛。

  1. /*
  2. * 分成 step 列进行排序
  3. */
  4. void sort(int step) {
  5. // col: 第几列
  6. for (int col = 0; col < step; col++) {
  7. // 对第 col 列进行排序
  8. // 对 [0, array.length) 进行插入排序
  9. for (int begin = col + step; begin < array.length; begin+=step) {
  10. int cur = begin;
  11. while (cur > col && cmp(cur, cur - step) < 0) {
  12. swap(cur, cur - step);
  13. cur -= step;
  14. }
  15. }
  16. }
  17. }

时间和空间复杂度

  • 最好、平均时间复杂度: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. AcWing 102. 最佳牛围栏

    农夫约翰的农场由 N 块田地组成,每块地里都有一定数量的牛,其数量不会少于1头,也不会超过2000头. 约翰希望用围栏将一部分连续的田地围起来,并使得围起来的区域内每块地包含的牛的数量的平均值达到最大 ...

  2. Swoole实现毫秒级定时任务

    项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是它的最小粒度是分钟级别,如果要求粒度是秒级别的,甚至毫秒级别的,crontab就无法满足,值得庆幸的是swoole ...

  3. JavaWeb中Servlet和Jsp跳转路径的写法

    最近学习时,常常要写一些页面之间的跳转或者前台和后端之间的跳转 下面总结一下自己对于这些跳转路径的写法 声明:以下讲到的jsp文件都默认在WebRoot目录下 1.表单(Jsp)->Servle ...

  4. Oracle如何以逗号分隔的字符串拆分为多行数据

    近期在工作中遇到某表某字段是可扩展数据内容,信息以逗号分隔生成的,现需求要根据此字段数据在其它表查询相关的内容展现出来,第一想法是切割数据,以逗号作为切割符,以下为总结的实现方法,以供大家参考.指教. ...

  5. ES6 箭头函数你正确使用了吗

    ES6 箭头函数你正确使用了吗 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 在ES6中允许使用"箭头&quo ...

  6. final修饰符(4)-"宏替换"

    对于一个final变量来说,不管它时类变量,实例变量还是局部变量,只要满足三个条件,这个final变量就不再是一个变量,而是一个直接量.final变量的一个重要用途,就是定义"宏变量&quo ...

  7. 计算机毕业设计选题大合集,含ssm,springboot,小程序,php,python

    1基于springboot医院急诊系统 2基于springboot校园闲置物品租售系统 3基于springboot校园闲置物品交易网站 4基于springboot图书网站 5基于springboot外 ...

  8. 【LeetCode】203.移除链表元素

    203.移除链表元素 知识点:链表:双指针 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 . 示例 ...

  9. Requests方法 --- json模块

    1.Json 简介:Json,全名 JavaScript Object Notation,是一种轻量级的数据交换格式,常用于 http 请求中 2.可以用 help(json),查看对应的源码注释内容 ...

  10. springboot-8-企业开发

    一.邮件发送 流程: mbqplwpheeyvgdjh 首先需要开启POS3/SMTP服务,这是一个邮件传输协议 点击开启 导入依赖 <!--mail--> <dependency& ...