双端队列
双端队列在单向队列的基础上解除了一部分限制:允许在队列的两端添加和删除元素。如此一来它便具有了队列和栈性质,这样方便我们解决一些问题。比如leetcode的239题(以后会在刷队列算法题的章节讲解)。
对于双端队列的封装只需要在原有队列封装的基础上加上unshift和pop方法即可,这里不再给出详细代码。PS:原有队列封装
优先级队列
优先级队列是一种比普通队列更加高效的数据结构,他每次出队的元素都是具有最高优先级的,可以理解为元素按照关键字进行排序。优先级队列可以使用数组、链表等数据结构来实现,但是堆是最常用的实现方式。
优先级队列封装
我们可以提供一个节点类用来当做堆的元素,为了方便值的比较,该类必须有一个valueOf方法。对于优先级队列类的封装,只需借助上节封装的堆结构,就可以简单快速的实现:
import { Heap } from './heap';
class PriorityNode<T> {
value: T;
priority: number; // 优先级
constructor(value: T, priority: number) {
this.value = value;
this.priority = priority;
}
valueOf() {
return this.priority;
}
}
class PriorityQueue<T> {
// 使用堆存储优先级节点
private heap: Heap<PriorityNode<T>>;
// 由传入的type决定是最大堆还是最小堆 默认是最小堆
constructor(type: HeapType = 0) {
this.heap = new Heap(type);
}
// 入队
enqueue(value: T, priority: number) {
this.heap.insert(new PriorityNode(value, priority));
}
// 出队
dequeue() {
return this.heap.extractTop()?.value;
}
// 获取队首元素
getFront() {
return this.heap.getTop()?.value;
}
// 非空判断
isEmpty() {
return this.heap.isEmpty();
}
// 获取队列中元素的个数
size() {
return this.heap.size();
}
}
// 测试
const pq = new PriorityQueue<string>();
pq.enqueue('c', 3);
pq.enqueue('d', 4);
pq.enqueue('e', 5);
pq.enqueue('a', 1);
pq.enqueue('b', 2);
while (!pq.isEmpty()) {
console.log(pq.dequeue());
}
// a
// b
// c
// d
// e
这里根据传入的type决定使用最大堆或者最小堆,如果你的优先级是大的值优先级高,那么可以传入1使用最大堆,反之使用默认的最小堆即可。