返回

用 TypeScript 实现高效二叉堆:深入浅出解读

前端

引言

二叉堆是一种完全二叉树,其中每个节点的值都大于或等于(最小堆)或小于或等于(最大堆)其子节点的值。这种独特的结构使二叉堆能够以 O(log n) 的时间复杂度快速查找最大值或最小值,非常适用于优先队列和堆排序算法。

TypeScript 实现

以下是使用 TypeScript 实现的二叉堆类:

class BinaryHeap {
    private heap: number[];
    private minHeap: boolean;

    constructor(minHeap = true) {
        this.heap = [];
        this.minHeap = minHeap;
    }

    insert(value: number) {
        this.heap.push(value);
        this.bubbleUp(this.heap.length - 1);
    }

    extract() {
        if (this.heap.length === 0) {
            return null;
        }

        let root = this.heap[0];
        this.heap[0] = this.heap.pop()!;
        this.bubbleDown(0);

        return root;
    }

    private bubbleUp(index: number) {
        while (index > 0) {
            let parentIndex = Math.floor((index - 1) / 2);
            if ((this.minHeap && this.heap[index] >= this.heap[parentIndex]) ||
                (!this.minHeap && this.heap[index] <= this.heap[parentIndex])) {
                break;
            }

            this.swap(index, parentIndex);
            index = parentIndex;
        }
    }

    private bubbleDown(index: number) {
        while (index < this.heap.length) {
            let leftChildIndex = 2 * index + 1;
            let rightChildIndex = 2 * index + 2;
            let swapIndex = index;

            if (leftChildIndex < this.heap.length) {
                if ((this.minHeap && this.heap[leftChildIndex] < this.heap[swapIndex]) ||
                    (!this.minHeap && this.heap[leftChildIndex] > this.heap[swapIndex])) {
                    swapIndex = leftChildIndex;
                }
            }

            if (rightChildIndex < this.heap.length) {
                if ((this.minHeap && this.heap[rightChildIndex] < this.heap[swapIndex]) ||
                    (!this.minHeap && this.heap[rightChildIndex] > this.heap[swapIndex])) {
                    swapIndex = rightChildIndex;
                }
            }

            if (swapIndex === index) {
                break;
            }

            this.swap(index, swapIndex);
            index = swapIndex;
        }
    }

    private swap(index1: number, index2: number) {
        let temp = this.heap[index1];
        this.heap[index1] = this.heap[index2];
        this.heap[index2] = temp;
    }
}

用法

以下代码展示了如何使用该二叉堆类:

const heap = new BinaryHeap();
heap.insert(5);
heap.insert(3);
heap.insert(10);
heap.insert(1);

while (heap.heap.length > 0) {
    console.log(heap.extract());
}

输出:

1
3
5
10

结论

本文深入浅出地讲解了二叉堆的数据结构,并用 TypeScript 语言实现了它。我们提供了详细的代码示例,展示了如何创建和使用二叉堆。了解二叉堆的原理和实现对于理解优先队列和堆排序算法至关重要。希望这篇文章能够帮助读者掌握二叉堆的概念,并在实际项目中高效地使用它。