/** * 优先级队列实现(使用最小堆) * 优先级高的任务(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;