第三部分 泛型与容器~~第11章 堆与优先级队列

96 阅读2分钟

前面两章介绍了Java中的基本容器类,每个容器类背后都有一种数据结构,ArrayList是动态数组,LinkedList是链表,HashMap/HashSet是哈希表,TreeMap/TreeSet是红黑树,本章介绍另一种数据结构:堆。之前我们提到过堆,那里,堆指的是内存中的区域,保存动态分配的对象,与栈相对应。这里的堆是一种数据结构,与内存区域和分配无关。

堆到底是什么结构呢?这个待会再细看。我们先来说明,堆有什么用?为什么要介绍它? 堆可以非常高效方便地解决很多问题, 比如:

  1. 优先级队列,我们之前介绍的队列实现类LinkedList是按添加顺序排列的,但现实中,经常需要按优先级,每次都应该处理当前队列中优先级最高的,高优先级的即使来得晚,也应该被优先处理。
  2. 求前K个最大的元素,元素个数不确定,数据量可能很大,甚至源源不断到来,但需要知道到目前为止的最大的前K个元素。这个问题的变体有:求前K个最小的元素,求第K个最大的元素,求第K个最小的元素。
  3. 求中值元素,中值不是平均值,而是排序后中间那个元素的值,同样,数据量可能很大,甚至源源不断到来。

堆还可以实现排序,称之为堆排序,不过有比它更好的排序算法,所以,我们就不介绍其在排序中的应用了。

Java容器中有一个类PriorityQueue, 表示优先级队列,它实现了堆,本章我们会详细介绍。关于如何使用堆高效解决前K个最大的元素和求中值元素,我们也会在本章中用代码实现并详细解释。

说了这么多好处,堆到底是什么呢?我们先来看堆的基本概念与算法。

11.1 堆的概念与算法

11.2 剖析PriorityQueue

11.3 堆和PriorityQueue的应用