JS手写最小堆(小顶堆)、最大堆(大顶堆)

442 阅读1分钟
  • 最小堆

    最小堆有两个方法:插入和移出。
    插入:将元素放置在堆的末尾,递归地将它与父节点元素对比,如果其值比父节点小就交换位置,直至其值大于等于父节点或移至到堆的首部。
    移出:堆中最小的值位于堆顶,先将其与堆尾元素交换位置,移出堆尾元素;将堆顶元素递归地与左右子节点元素比较,如果其值大于子节点就交换位置,直至其值小于等于子节点。

    let heap = [];
    
    function swap(index1, index2) {
    
        [heap[index1], heap[index2]] = [heap[index2], heap[index1]]
    
    }
    
    function shiftup(index) {
    
        let parentIndex = Math.floor((index - 1) / 2);
    
        if (index != 0 && heap[parentIndex] > heap[index]) {
    
            swap(parentIndex, index);
    
            shiftup(parentIndex);
    
        }
    
    }
    
    function shiftDown(index) {
    
        let leftNodeIndex = (index + 1) * 2 - 1, rightNodeIndex = (index + 1) * 2
    
        if (leftNodeIndex < heap.length && heap[leftNodeIndex] < heap[index]) {
    
            swap(leftNodeIndex, index);
    
            shiftDown(leftNodeIndex);
    
        }
    
        if (rightNodeIndex < heap.length && heap[rightNodeIndex] < heap[index]) {
    
            swap(rightNodeIndex, index);
    
            shiftDown(rightNodeIndex);
    
        }
    
    }
    
    function insert(val) {
    
        heap.push(val);
    
        shiftup(heap.length - 1);
    
    }
    
    function remove() {
    
        swap(0, heap.length - 1);
    
        let temp = heap.pop();
    
        shiftDown(0);
    
        return temp;
    
    }
    
  • 最大堆

    最大堆与最小堆的实现思路一样,只是需要父子节点交换的条件不同;最大堆的最大值位于堆顶,所以需要在父节点小于子节点时进行交换位置。

    let heap = [];
    
    function swap(index1, index2) {
    
        [heap[index1], heap[index2]] = [heap[index2], heap[index1]]
    
    }
    
    function shiftup(index) {
    
        let parentIndex = Math.floor((index - 1) / 2);
    
        if (index != 0 && heap[parentIndex] < heap[index]) {
    
            swap(parentIndex, index);
    
            shiftup(parentIndex);
    
        }
    
    }
    
    function shiftDown(index) {
    
        let leftNodeIndex = (index + 1) * 2 - 1, rightNodeIndex = (index + 1) * 2
    
        if (leftNodeIndex < heap.length && heap[leftNodeIndex] > heap[index]) {
    
            swap(leftNodeIndex, index);
    
            shiftDown(leftNodeIndex);
    
        }
    
        if (rightNodeIndex < heap.length && heap[rightNodeIndex] > heap[index]) {
    
            swap(rightNodeIndex, index);
    
            shiftDown(rightNodeIndex);
    
        }
    
    }
    
    function insert(val) {
    
        heap.push(val);
    
        shiftup(heap.length - 1);
    
    }
    
    function remove() {
    
        swap(0, heap.length - 1);
    
        let temp = heap.pop();
    
        shiftDown(0);
    
        return temp;
    
    }