This commit is contained in:
张成
2025-12-30 15:46:18 +08:00
parent d14f89e008
commit 65833dd32d
29 changed files with 2416 additions and 1048 deletions

View File

@@ -0,0 +1,215 @@
/**
* 优先级队列实现(使用最小堆)
* 优先级高的任务priority值大会优先出队
*/
class PriorityQueue {
constructor() {
this.heap = [];
}
/**
* 获取父节点索引
*/
parent(index) {
return Math.floor((index - 1) / 2);
}
/**
* 获取左子节点索引
*/
leftChild(index) {
return 2 * index + 1;
}
/**
* 获取右子节点索引
*/
rightChild(index) {
return 2 * index + 2;
}
/**
* 交换两个节点
*/
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
/**
* 上浮操作(插入时使用)
*/
bubbleUp(index) {
if (index === 0) return;
const parentIndex = this.parent(index);
const current = this.heap[index];
const parent = this.heap[parentIndex];
// 优先级高的在前priority值大如果优先级相同创建时间早的在前
if (
current.priority > parent.priority ||
(current.priority === parent.priority && current.createdAt < parent.createdAt)
) {
this.swap(index, parentIndex);
this.bubbleUp(parentIndex);
}
}
/**
* 下沉操作(删除时使用)
*/
bubbleDown(index) {
const leftIndex = this.leftChild(index);
const rightIndex = this.rightChild(index);
let largest = index;
const current = this.heap[index];
// 比较左子节点
if (leftIndex < this.heap.length) {
const left = this.heap[leftIndex];
if (
left.priority > current.priority ||
(left.priority === current.priority && left.createdAt < current.createdAt)
) {
largest = leftIndex;
}
}
// 比较右子节点
if (rightIndex < this.heap.length) {
const right = this.heap[rightIndex];
const largestNode = this.heap[largest];
if (
right.priority > largestNode.priority ||
(right.priority === largestNode.priority && right.createdAt < largestNode.createdAt)
) {
largest = rightIndex;
}
}
if (largest !== index) {
this.swap(index, largest);
this.bubbleDown(largest);
}
}
/**
* 添加任务到队列
* @param {Object} task - 任务对象,必须包含 priority 和 createdAt 属性
*/
push(task) {
if (!task.hasOwnProperty('priority')) {
task.priority = 5; // 默认优先级
}
if (!task.hasOwnProperty('createdAt')) {
task.createdAt = Date.now();
}
this.heap.push(task);
this.bubbleUp(this.heap.length - 1);
}
/**
* 取出优先级最高的任务
* @returns {Object|null} 任务对象或null
*/
pop() {
if (this.heap.length === 0) {
return null;
}
if (this.heap.length === 1) {
return this.heap.pop();
}
const top = this.heap[0];
this.heap[0] = this.heap.pop();
this.bubbleDown(0);
return top;
}
/**
* 查看优先级最高的任务(不移除)
* @returns {Object|null} 任务对象或null
*/
peek() {
return this.heap.length > 0 ? this.heap[0] : null;
}
/**
* 获取队列大小
* @returns {number}
*/
size() {
return this.heap.length;
}
/**
* 检查队列是否为空
* @returns {boolean}
*/
isEmpty() {
return this.heap.length === 0;
}
/**
* 清空队列
*/
clear() {
this.heap = [];
}
/**
* 查找任务
* @param {Function} predicate - 查找条件函数
* @returns {Object|null} 任务对象或null
*/
find(predicate) {
return this.heap.find(predicate) || null;
}
/**
* 移除任务
* @param {Function} predicate - 查找条件函数
* @returns {boolean} 是否成功移除
*/
remove(predicate) {
const index = this.heap.findIndex(predicate);
if (index === -1) {
return false;
}
if (index === this.heap.length - 1) {
this.heap.pop();
return true;
}
// 将最后一个元素移到当前位置
this.heap[index] = this.heap.pop();
// 重新调整堆
const parentIndex = this.parent(index);
if (index > 0 && this.heap[parentIndex] &&
(this.heap[index].priority > this.heap[parentIndex].priority ||
(this.heap[index].priority === this.heap[parentIndex].priority &&
this.heap[index].createdAt < this.heap[parentIndex].createdAt))) {
this.bubbleUp(index);
} else {
this.bubbleDown(index);
}
return true;
}
/**
* 转换为数组(用于调试)
* @returns {Array}
*/
toArray() {
return [...this.heap];
}
}
module.exports = PriorityQueue;