JDK中的java.util.PriorityQueue实现方法不同于上面这些方法,它是基于堆的。
堆本质是一棵二叉树,其中所有的元素都可以按全序语义(参见附录说明)进行比较。用 堆来进行存储需要符合以下规则:
1.数据集中的元素可以用全序语义进行比较;
2.每个节点的元素必须大于或小于该节点的孩子节点的元素;
3.堆是一棵完全二叉树。
用堆来实现优先队列,跟节点始终是优先权最大的元素节点。
插入的思路是这样的,当插入一个元素时。先将这个元素插入到队列尾,然后将这个新插入的元素和它的父节点进行优先权的比较,如果比父节点的优先权要大,则和父节点呼唤位置,然后再和新的父节比较,直到比新的父节点优先权小为止,参见图2和图3
这个寻找新插入元素位置的过程对应于java.util.PriorityQueue源代码中的
Java代码
Java代码
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
Java代码
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
不是二叉树结构吗?不是节点吗,为什么这里看到的是操作数组?我原来有这样的 疑问,因为之前自己实现过的二叉树只是止于链式结构。然而,树存在如下特点:
1.根节点的数据总是在数组的位置[0]
2.假设一个非跟节点的数据在数组中的位置[i],那么它的父节点总是在位置[(i-1)/2]
3.假设一个节点的数据在数组中的位置为[i],那么它的孩子(如果有)总是在下面的这两个位置:
左孩子在[2*i+1]
右孩子在[2*i+2]
基于这些特点,用数组来表示数会更加方便。源代码中int parent = (k - 1) >>> 1等价于int parent = (k - 1) / 2;对于这里涉及到的位运算,可以参见附录文档。
从优先队列中删除优先权最大的元素的思路是将队列尾的元素值赋给跟节点,队列为赋 值为null。然后检查新的根节点的元素优先权是否比左右子节点的元素的优先权大,如果 比左右子节点的元素的优先权小,就交换位置,重复这个过程,直到秩序正常。参见图4
相关推荐
下面我们研究一下JDK中PriorityQueue的实现方式。 首先,我们可以创建一个优先队列,向其中添加三个元素。public PriorityQueue(int initialCapacity, Comparator<? super E> comparator)这个构造函数将数组的初始...
`DelayQueue`是一个基于优先级队列(PriorityQueue)实现的无界阻塞队列,它的主要特性是元素只有在达到指定延迟时间后才能被消费。这种队列常用于实现定时任务调度、缓存过期策略等场景。 1. **延迟元素的概念** ...
Queue接口代表队列,提供了先进先出(FIFO)的数据结构,例如LinkedList可以作为Queue的实现,还有PriorityQueue实现了优先队列。 在UML图中,可以看到这些接口和类的继承关系,以及它们之间的依赖关系。例如,...
PriorityQueue在JDK中内置,基于二叉堆数据结构实现,特别是最小堆,这意味着队列头部的元素总是具有最低的优先级。在Java 7中,PriorityQueue的底层实现是一个近似完全二叉树的数组,保证了队列的高效操作。 ...
`PriorityQueue`则是一种优先队列,根据元素的自然顺序或比较器进行排序。 `Map`接口存储键值对,不允许键重复。`HashMap`是基本的实现,它通过哈希表提供快速的插入、删除和查找操作。`TreeMap`使用红黑树保持键的...
具体实现上,Java提供了多种队列实现,如`ArrayDeque`、`LinkedList`或`PriorityQueue`等。在排队叫号系统中,我们可能选择`LinkedBlockingQueue`,因为它是一个线程安全的队列,特别适合多线程环境。`...
- **Queue**: 用于处理队列操作的接口和实现,如ArrayDeque和PriorityQueue。 4. **异常处理** - **Exception**: 所有检查性异常的基类,如IOException、SQLException。 - **RuntimeException**: 非检查性异常的...
Java的`PriorityQueue`类实现了优先队列。 5. **集合和映射表**: Java集合框架包括List、Set和Map接口,以及它们的各种实现类,如ArrayList、LinkedList、HashSet、TreeSet、HashMap和TreeMap等。这些集合类提供了...
4. **优先队列**:PriorityQueue实现了优先队列数据结构,可以高效地执行插入和删除操作,常用于优先级调度和堆排序。 5. **树结构**:TreeSet和TreeMap使用红黑树实现,提供O(log n)的时间复杂度,支持高效的插入...
- `PriorityQueue`:基于堆结构,实现优先队列,元素按优先级排序。 `Map`接口则用于存储键值对,主要有以下几个实现类: 1. `TreeMap`:基于红黑树,保持键的有序性。 2. `HashMap`:基于哈希表,提供快速的查找...
JDK中的`java.util`包包含了多种内置数据结构,如ArrayList、LinkedList、Stack、Queue(PriorityQueue)、HashSet、HashMap等。这些数据结构和算法已经过优化,适用于大多数情况,但根据具体需求,有时可能需要...
Java中的PriorityQueue类就是基于堆实现的优先队列。 7. 图数据结构:图由顶点和边组成,可以表示复杂的关系。图的遍历算法如深度优先搜索(DFS)和广度优先搜索(BFS)是图算法的基础。 8. 排序算法:排序是数据...
16. **集合框架的高级特性**:TreeSet、TreeMap的原理,Comparator接口,优先队列PriorityQueue,以及并发集合类如ConcurrentHashMap。 17. **Java SE的最新特性**:例如Java 8中的Lambda表达式、Stream API,Java ...
实现类有LinkedList(作为双端队列)、PriorityQueue和ArrayQueue。 2. **Map接口**: - **Map**:用于存储键值对,键是唯一的,而值则可以重复。实现类有HashMap、LinkedHashMap、Hashtable和TreeMap。 - **...
此外,`PriorityQueue`是一种基于优先堆实现的队列,元素按照优先级进行排序,常用于实现调度和事件处理。`Deque`接口代表双端队列,可以支持从两端添加和移除元素,`ArrayDeque`是其高效的实现。 `Collections`...
Queue接口的特性是处理数据有序地按照先进先出(FIFO)的顺序进行,常用于任务调度等场景,其常用实现类有PriorityQueue和LinkedList等。 具体到实现类,ArrayList是一个可以自动增长容量的集合,它本质上是一个...
- **JDK中的队列实现**:ConcurrentLinkedQueue(高性能非阻塞队列)和BlockingQueue(阻塞队列,包含7种实现)。 - **队列分类**:双端队列(Deque)和单端队列(如LinkedList、ArrayBlockingQueue、...
Java的`PriorityQueue`实现了最小堆。 算法则是解决问题的步骤或方法。Java中的关键算法包括: 1. 排序算法:如冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序,它们用于将元素按特定顺序排列。 2. ...
除了基本的队列操作外,Java还提供了PriorityQueue等具有优先级功能的队列。 在Java集合框架中,各种集合类型的自动扩容机制是提高性能的关键。当集合的容量不足以容纳更多元素时,会进行扩容操作,这是通过定义...