0%

Java8在2014年3月份推出的,而历经曲折的Java9终于终于在2017年9月21日发布,中间历经3年多时间,Java9提供了超过150项新功能特性,包括备受期待的模块化系统、可交互的 REPL 工具:jshell,JDK 编译工具,Java 公共 API 和私有代码,以及安全增强、扩展提升、性能管理改善等。可以说Java 9是一个庞大的系统工程,完全做了一个整体改变。Java8中最核心的新特性就是Lambda表达式和Stream API,那么对于Java9来说其中最核心莫过于模块化系统和JShell命令。

虽然已经用过了一些Java8的新特性,但是总来没有仔细总结一下。Java8自从2014年就发布了,到目前为止只有一小部分公司在用JDK7及其以下的版本,大部分已经迁移至Java8,甚至Java11(关于Java9和Java11的特性我会在之后两篇文章中记述),目前只看Java8那些最主要的、也是最常用的新特性,我到目前为止用到的最多的也就是Stream API和Lambda表达式,新时间日期的API也比较常用。

本篇文章记述的是堆排序,这个名字看起来好像又要介绍一个排序算法,但是排序算法是次要的,主要的是一个数据结构——堆。堆排序问题就是堆这种数据结构所衍生出来的一个应用,我们先了解一下优先队列的概念。普通的队列就是满足先进先出、后进后出的一个结构。那么优先级队列呢?出队顺序和入队顺序无关,和优先级相关,这就比如在医院看病,肯定是急诊病人优先看病。

注解这个东西自从SpringBoot以来一直是Java开发者们必备的生存技巧呀,我们平时几乎大部分时间都是面向注解编程,通过注解我们可以节约大量的时间。用过了这么多的注解,那么我们否有关注过注解的实现原理呢?所以本篇文章主要是讲述注解的有关操作,自己实现一个注解来体会注解的实现原理,注解也不是特别高深的东西,掌握了自然就明白了。

归并排序和快速排序是两种稍微复杂的排序算法,它们用的都是分治的思想,代码都通过递归来实现,过程非常相似。归并排序算法是一种在任何情况下时间复杂度都比较稳定的排序算法,这也使它存在致命的缺点,即归并排序不是原地排序算法,空间复杂度比较高,是 O(n)。正因为此它也没有快排应用广泛。快速排序算法虽然最坏情况下的时间复杂度是 O(n²),但是平均情况下时间复杂度都是 O(nlogn)。且快速排序算法时间复杂度退化到 O(n²) 的概率非常小,我们可以通过合理地选择基准值来避免这种情况。

快速排序(Quick Sort)被称为20世纪对世界影响最大的算法之一,现在我们来看快速排序算法,习惯性把它简称为快排,快排利用的也是分治思想。乍看起来,它有点像归并排序,但是思路其实完全不一样。现在,我们先来看下快排的核心思想,最后将讲述快速排序的两个优化方案,其实还有一种三路快排的优化方案也是可以的,但是本片文章重点在于快速排序的原理和实现,所以三路快排的优化方案不会出现在这篇文章里,以后再详细记录一下。

之前几篇文章我介绍了三种O(n²)的排序算法 《O(n²)的三个排序算法》 (选择排序、插入排序和冒泡排序)以及它们的优化,然后顺便还写了一篇希尔排序的文章 《插入排序的优化之希尔排序》 ,但是其实用的比较多的还是直接插入排序,它们比较适合于小规模数据的排序 。下面我将记录时间复杂度为nlog(n)的几种排序算法之一 —— 归并排序算法,这种排序算法适合大规模的数据排序,比之前的O(n²)的三种排序算法更为常用,在学习之前我们可以先对比一下nlog(n)和n²是什么概念。

希尔排序是插入排序的一种,又称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法,可以说它是插入排序的高级版。我们可以先回顾一下直接插入排序的过程:

排序前将第一个元素看成有序的数列

  • 第1趟排序后:得到一个长度为2的有序数列
  • 第2趟排序后:得到一个长度为3的有序数列
  • 第3趟排序后:得到一个长度为4的有序数列
  • ……..每趟插入排序,都可以将一个无序值插入一个有序数列,直到全部元素有序