📅  最后修改于: 2023-12-03 15:01:47.432000             🧑  作者: Mango
优先队列是一种特殊的队列数据结构,每个元素都被赋予一个优先级,在队列中高优先级的元素被优先处理。
在Javascript中,我们可以通过数组和堆来实现优先队列。这里将介绍两种常见的实现方式。
class PriorityQueue {
constructor() {
this.queue = [];
}
// 添加元素到队列
enqueue(element, priority) {
const queueElement = { element, priority };
let added = false;
for (let i = 0; i < this.queue.length; i++) {
if (queueElement.priority < this.queue[i].priority) {
this.queue.splice(i, 0, queueElement);
added = true;
break;
}
}
if (!added) {
this.queue.push(queueElement);
}
}
// 移除并返回队列中第一个元素
dequeue() {
if (!this.isEmpty()) {
return this.queue.shift().element;
}
return null;
}
// 返回队列中第一个元素
front() {
if (!this.isEmpty()) {
return this.queue[0].element;
}
return null;
}
// 判断队列是否为空
isEmpty() {
return this.queue.length === 0;
}
// 返回队列的长度
size() {
return this.queue.length;
}
// 清空队列
clear() {
this.queue = [];
}
}
// 使用例子
const priorityQueue = new PriorityQueue();
priorityQueue.enqueue('Task 1', 3);
priorityQueue.enqueue('Task 2', 1);
priorityQueue.enqueue('Task 3', 2);
console.log(priorityQueue.front()); // 输出 "Task 2"
console.log(priorityQueue.dequeue()); // 输出 "Task 2"
console.log(priorityQueue.size()); // 输出 2
class Heap {
constructor() {
this.heap = [];
}
// 获取父节点的索引
getParentIndex(index) {
return Math.floor((index - 1) / 2);
}
// 获取左子节点的索引
getLeftChildIndex(index) {
return index * 2 + 1;
}
// 获取右子节点的索引
getRightChildIndex(index) {
return index * 2 + 2;
}
// 上移操作
siftUp(index) {
let parentIndex = this.getParentIndex(index);
while (index > 0 && this.heap[parentIndex] > this.heap[index]) {
[this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];
index = parentIndex;
parentIndex = this.getParentIndex(index);
}
}
// 下移操作
siftDown(index) {
const leftChildIndex = this.getLeftChildIndex(index);
const rightChildIndex = this.getRightChildIndex(index);
let swapIndex = index;
if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] < this.heap[swapIndex]) {
swapIndex = leftChildIndex;
}
if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] < this.heap[swapIndex]) {
swapIndex = rightChildIndex;
}
if (index !== swapIndex) {
[this.heap[index], this.heap[swapIndex]] = [this.heap[swapIndex], this.heap[index]];
this.siftDown(swapIndex);
}
}
// 入队列
enqueue(value) {
this.heap.push(value);
this.siftUp(this.heap.length - 1);
}
// 出队列
dequeue() {
if (!this.isEmpty()) {
const front = this.heap[0];
const last = this.heap.pop();
if (!this.isEmpty()) {
this.heap[0] = last;
this.siftDown(0);
}
return front;
}
return null;
}
// 返回队列中第一个元素
front() {
if (!this.isEmpty()) {
return this.heap[0];
}
return null;
}
// 判断队列是否为空
isEmpty() {
return this.heap.length === 0;
}
// 返回队列的长度
size() {
return this.heap.length;
}
// 清空队列
clear() {
this.heap = [];
}
}
// 使用例子
const priorityQueue = new Heap();
priorityQueue.enqueue(3);
priorityQueue.enqueue(1);
priorityQueue.enqueue(2);
console.log(priorityQueue.front()); // 输出 1
console.log(priorityQueue.dequeue()); // 输出 1
console.log(priorityQueue.size()); // 输出 2
以上是使用数组和堆来实现Javascript中优先队列的两种常见方式。根据实际需求和性能要求,选择合适的实现方式来管理有优先级的元素队列。