《JavaScript算法》优先队列

127 阅读1分钟

优先队列是一种抽象数据类型,它支持插入一个元素,并从所有插入的元素中删除最小(或最大)元素的操作。JavaScript 中没有内置的优先队列数据结构,但我们可以使用数组、链表或堆来实现它。

这里给出一个使用最小堆实现的优先队列的基本模板:

class PriorityQueue {
    constructor(compareFunc = (a, b) => a < b) {
        this.queue = [];
        this.compare = compareFunc;
    }

    // 入队
    enqueue(val) {
        this.queue.push(val);
        this._heapifyUp();
    }

    // 出队
    dequeue() {
        if (this.size() === 1) return this.queue.pop();
        const val = this.queue[0];
        this.queue[0] = this.queue.pop();
        this._heapifyDown();
        return val;
    }

    // 返回队首元素
    front() {
        return this.queue[0];
    }

    // 返回队列大小
    size() {
        return this.queue.length;
    }

    _heapifyUp() {
        let idx = this.size() - 1;
        while (idx > 0 && this.compare(this.queue[idx], this.queue[Math.floor((idx - 1) / 2)])) {
            [this.queue[idx], this.queue[Math.floor((idx - 1) / 2)]] = [this.queue[Math.floor((idx - 1) / 2)], this.queue[idx]];
            idx = Math.floor((idx - 1) / 2);
        }
    }

    _heapifyDown() {
        let idx = 0;
        while ((2 * idx + 1) < this.size()) {
            let smallerIdx = 2 * idx + 1;
            if (2 * idx + 2 < this.size() && this.compare(this.queue[2 * idx + 2], this.queue[smallerIdx])) {
                smallerIdx = 2 * idx + 2;
            }
            if (this.compare(this.queue[idx], this.queue[smallerIdx])) break;
            [this.queue[idx], this.queue[smallerIdx]] = [this.queue[smallerIdx], this.queue[idx]];
            idx = smallerIdx;
        }
    }
}