Skip to content

JavaScript实现一个最大堆 #49

Open
@funnycoderstar

Description

@funnycoderstar
class Heap {
    constructor() {
        this.data = [];
    }
    build(arr) {
        this.data = [];
        for (let i = 0; i < arr.length; i++) {
            this.insert(arr[i]);
        }
    }
    print() {
        console.log(this.data);
    }
    insert(value) {
        // 先把当前元素加到最后一个位置

        this.data.push(value);
        // 获取当前元素的index
        let nIndex = this.data.length - 1;
        // 获取父节点
        let nParentIndex = Math.floor((nIndex - 1) / 2);
        while (nParentIndex >= 0) {
            // 当前节点大于父节点,则交换顺序
            if (this.data[nIndex] > this.data[nParentIndex]) {
                [this.data[nIndex], this.data[nParentIndex]] = [
                    this.data[nParentIndex],
                    this.data[nIndex],
                ];
            }
            // 当前父元素赋值为 nIndex
            nIndex = nParentIndex;
            // 获取再上一个父元素的下标
            nParentIndex = Math.floor((nIndex - 1) / 2);
        }
    }
    // 删除最大节点
    delete() {
        if (this.data.length <= 1) {
            return (this.data = []);
        }
        // 把最后一个节点临时补到原本堆顶的位置
        // 删除第一个节点,将最后一个子节点补充到根节点
        this.data[0] = this.data.pop();
        let len = this.data.length;
        let curIndex = 0;
        // 暂时处于堆顶位置的节点和它的左右孩子节点进行比较
        while (curIndex < len) {
            let nLeftIndex = 2 * curIndex + 1;
            let nRightIndex = 2 * curIndex + 1;
            let maxLeafIndex = nLeftIndex;
            // 找到左右节点中较大的一个 nSelectIndex
            if (nRightIndex < len) {
                maxLeafIndex =
                    this.data[nLeftIndex] > this.data[nRightIndex] ? nLeftIndex : nRightIndex;
            }
            // 判断 maxLeafIndex 如果大于 curIndex, 则交换
            if (maxLeafIndex < len && this.data[maxLeafIndex] > this.data[curIndex]) {
                [this.data[maxLeafIndex], this.data[curIndex]] = [
                    this.data[curIndex],
                    this.data[maxLeafIndex],
                ];
            }
            curIndex = maxLeafIndex;
        }
    }
}

const heap = new Heap();
heap.build([1, 3, 4, 2]);
heap.print(); // [ 4, 2, 3, 1 ]
heap.delete();
heap.print(); // [ 3, 2, 1 ]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions