本文介绍插入排序和希尔排序,插入排序是较为常见的排序算法,希尔排序也是基础的排序算法,废话不多说,具体来看一下两种算法。

插入排序

插入排序的基本思想是拿到下一个插入元素,在已经有序的待排数组部分找到自己的位置,然后进行数据的移动,完成该元素的排序,依次类推,直到整个待排数组有序,初始状态待排数组的有序部分仅有一个元素。代码如下:

public static void sort(int[] nums) { Arrays.nonBlank(nums); for (int i = 1; i < nums.length; i++) { for (int j = i; j > 0; j--) { if (nums[j] < nums[j - 1]) { int temp = nums[j]; nums[j] = nums[j - 1]; nums[j - 1] = temp; } } }}

上面这种方式两两数据交换,换到合适位置,每次交换多了两次赋值操作,下面是实现的标准模式:

public static void sort2(int[] nums) { Arrays.nonBlank(nums); for (int i = 1; i < nums.length; i++) { int temp = nums[i]; // 记录插入值 int j; for (j = i; j > 0 && temp < nums[j - 1]; j--) { nums[j] = nums[j - 1];// 寻找位置,能够减少赋值的次数 } nums[j] = temp;// 找到位置,完毕 }}

以上就是插入排序的两种实现方式,并没有改进,其时间复杂度为O(n^2),妥妥的两层循环,另外插入排序是稳定排序,存不存在一种改进的插入排序呢?答案是有的,这就是我们下面要介绍的希尔排序;

希尔排序

希尔排序是插入排序的改进版。主要改进思路是减少插入排序中数据的移动次数,设置步长,在初始数组较大时取较大步长,通常初始步长为待排数组长度1/2,此时只有两个元素比较,交换一次,此时数组为部分有序数组;之后步长依次减半直至步长为1,即为插入排序,此时数组已接近有序,所以插入元素时数据移动次数会相对较少,效率得到提高,实现代码如下:

public static void sort(int[] nums) { Arrays.nonBlank(nums); int N = 0 + nums.length; for (int gap = N / 2; gap > 0; gap /= 2) { for (int i = gap; i < N; i++) { insert(nums, i, gap); } }}​private static void insert(int[] nums, int i, int gap) { int inserted = nums[i]; int j; for (j = i - gap; j > 0 && nums[j] > inserted; j -= gap) { nums[j + gap] = nums[j]; } nums[j + gap] = inserted;}

既然为改进算法,那么相比较插入排序,希尔排序的到底快了多少呢?为此特意去找了资料,一般书上都说希尔排序的时间复杂度是O(n^3/2),但是学过算法的都知道有最坏时间复杂度的,希尔排序的时间复杂度其实是和增列序列有关系的,即我们程序实现的步长,{1,2,4,8,...}这种序列就是我们程序中实现的这种,并不是很好的增量序列,使用这个增量序列的时间复杂度(最坏情形)是O(n^2),Hibbard提出了另一个增量序列{1,3,7,...,2^k-1}(质数增量),这种序列的时间复杂度(最坏情形)为O(n^1.5),这个提高就很厉害了,只是修改一个算法的一个参数;Sedgewick提出了几种增量序列,其最坏情形运行时间为O(n^1.3),其中最好的一个序列是{1,5,19,41,109,...},最后这个就当是科普小知识吧,因为给你你也不一定能用,请原谅我的直接,当别人说希尔排序的最坏时间复杂度是O(n^2)的时候,你也可以给他们科普一下,希尔排序的最坏时间复杂度是可以做到O(n^1.3)的。

总结

插入排序感觉是最为直观的排序方式,如果有人没有学过算法,人们最直接的排序方式就是,一个一个去找数字的位置,确定,然后再去找下一个,所以思想很简单,但是我们看到即时这样简单地排序思想,到了希尔这里,也能玩出花,所以对任何东西,尤其是简单的事物,都要心怀敬畏啊。

构成我们学习最大障碍的是已知的东西,而不是未知的东西。——贝尔纳

希尔排序 最坏时间_排序算法(2)相关推荐

  1. 希尔排序 最坏时间_希尔排序算法

    希尔排序(Shell's Sort)是插入排序的一种,又称"缩小增量排序",是直接插入排序算法经过改进之后的一种更高效的版本.希尔排序为了加快速度简单地改进了插入排序,交换不相邻的 ...

  2. 希尔排序 最坏时间_算法篇----希尔排序

    在之前的文章里,我们讲解了插入排序,而希尔排序相当于对插入排序的一种优化.在这里我们简单回顾下插入排序,插入排序的核心思想是,从数组首位开始,通过遍历,将相邻的两个元素进行排列,小的元素放在前面,大的 ...

  3. 算法导论-9.3-3-快速排序-最坏时间O(nlgn)

    一.题目 假定元素的值不同,说明如何才能使快速排序在最坏情况下以O(nlgn)时间运行 二.思考 要改善最坏情况的下运行时间,就要从划分入手,保证即使是最坏情况,也要尽量均衡地划分. 因此,使用SEL ...

  4. 中希尔排序例题代码_【数据结构与算法】这或许是东半球分析十大排序算法最好的一篇文章...

    码农有道 历史文章目录(请戳我) 关于码农有道(请戳我) 前言 本文全长 14237 字,配有 70 张图片和动画,和你一起一步步看懂排序算法的运行过程. 预计阅读时间 47 分钟,强烈建议先收藏然后 ...

  5. 中希尔排序例题代码_超全面分析十大排序算法

    点击上方"零一视界",选择"星标"公众号 资源干货,第一时间送达 作者 | 不该相遇在秋天 责编 | 程序员小吴 前言 本文全长 14237 字,配有 70 张 ...

  6. 中希尔排序例题代码_十大经典排序算法最强总结

    排序算法属于经典基础算法基本功,笔试面试基本都会涉及和考察的,有原题也有变化,不过基础的几大排序算法还是得尽可能熟悉,能在思路熟悉的前提下手写出代码就更好了. ❝为了防止不提供原网址的转载,特加原文链 ...

  7. java 快速排序算法简单_排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序......

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

  8. 希尔排序python 简书_排序:希尔排序(算法)

    文 | 莫若吻 (注:如果想更好的理解希尔排序,请先看看我的上一篇博客插入排序,希望会对你有帮助.) 一.简介 希尔排序(Shell Sort)是插入排序的一种算法,是对直接插入排序的一个优化,也称缩 ...

  9. ds排序--希尔排序_排序算法 - 希尔排序分析及优化

    希尔排序 1 算法思想 希尔排序,也被称为递减增量排序,是简单插入排序的一种改进版本. 在插入排序中,如果待排序列中的某个元素,距离有序数列中待插入位置非常远,就需要比较很多次才可以到达插入位置,这是 ...

最新文章

  1. Spring之IoC总结帖
  2. Java常用类之【Math类、Random类、System类、Runtime类】
  3. 关于Windows Unicode 编码的问题
  4. HTML与CSS基础之常用选择器(一)
  5. MPEG的完整形式是什么?
  6. 【转】掌握Azure订阅的关键概念和术语
  7. 计算机软件保护问题研究,计算机软件专利保护问题-研究.pdf
  8. 物联网四大产业群的典型应用场景
  9. 构造者模式(Builder)
  10. 虚拟机中XP系统激活
  11. 如何开发一款游戏:游戏开发流程及所需工具
  12. python做meta分析_浅析python的metaclass
  13. div水平垂直居中的四种方式
  14. hc05模块android代码,Arduino使用HC05蓝牙模块与手机连接
  15. php中lpush(),LPUSH命令_视频讲解_用法示例-redis编程词典-php中文网
  16. 8.1 向量及其线性运算
  17. 读《创业36条军规》(五)放下身段死缠烂打
  18. UML画图总结以及浅谈UNL九种图
  19. GEOTRANS 3.7 用户使用手册 - 区域和控件
  20. JAVA:日期时间范围查询0点到23点59分59秒之间

热门文章

  1. java用switch语句根据分数输出学生等级
  2. postgre管理员 无法访问表_postgresql – 授予用户对所有表的访问权限
  3. java中的异常处理语句_Java中实现异常处理的基础知识
  4. Ajax链接输出数据库
  5. diag开关什么意思_双控开关接线图_一灯双控开关接线图_单联双控开关接线图_双控开关接线图实物图...
  6. java产生字符函数_java生成字符串md5函数类(javaSE)
  7. java file 字符串_Java读取一个文本文件拼接成一个字符串(readFileToString)
  8. 系统相机裁剪比例_如何正确设置相机:6个最常见的错误,你还在犯错吗?
  9. fx5u以太网通讯设置_操作示例 | 实现S7300和FX5U的数据交换
  10. php实现 字符串加密(分类分布分工,化不可能为可能)