react的优先队列-小顶堆

154 阅读2分钟

1.前言:

react中schedule阶段,会根据lane模型中的参数进行排序,形成优先队列,进而实现调度的优先级执行

2.小顶堆的介绍:

堆类似完全二叉树的数据结构,但通常用数组实现
所有父结点都比子结点小,小顶堆的堆顶是最小值
时间复杂度:
    1.维护堆的排序:O(nlogn)
    2.获取最值:O(1)
空间复杂度:O(n)

3.堆的存储结构:

使用数组来表示链式结构:
由于堆本身是一棵完全二叉树,所以我们可以把每个结点,按照层序映射到一个顺序存储的数组中,然后利用每个结点在数组中的下标,来确定结点之间的关系
描述堆结点下表和结点之间的关系:
            1.根结点编号:
                   可以使用01
            2.孩子结点编号:
                   对于编号为i的结点,左子树编号为2i+1,右子树编号为2i+2
            3.父结点编号:
                   当编号为i的结点,它的父结点编号为(i-1)/2
    

4.小顶堆的方法:

    1.下沉方法:
        堆顶出堆,将堆底的数据放到堆顶
        从堆顶开始,通过循环,比较左右两个子结点,和其中最小的结点交换,直到小于等于左右两个子结点(叶子结点)


    2.上浮方法:
        新元素插入到堆底
        从堆底开始,通过循环,比较父结点,若小于父结点则进行交换,直至大于父结点
        

5.小顶堆的实现:

   // 小顶堆
    class MinHeap {
        constructor (array = []) {
            this.heapArray = []
            for (let index = 0; index < array.length; index++) {
                this.heapArray.push(array[index])
            }
        }

   //下沉
    sink () {
        let curIdx = 0
        let len = this.heapArray.length
        let leftChild = 2 * curIdx + 1
        let rightChild = 2 * curIdx + 2
        let minChild = leftChild
        while (leftChild <= len - 1) { //叶节点跳出循环
            // 获取最小的子节点索引
            // 如果没有右节点,直接选择左节点,否则比较大小
            minChild = (rightChild > len - 1 || this.heapArray[leftChild] < this.heapArray[rightChild]) ? leftChild : rightChild
            // 交换节点
            if (this.heapArray[curIdx] > this.heapArray[minChild]) {
                [this.heapArray[curIdx], this.heapArray[minChild]] = [this.heapArray[minChild], this.heapArray[curIdx]]
                curIdx = minChild
                leftChild = 2 * curIdx + 1
                rightChild = 2 * curIdx + 2
            } else {
                return
            }
        }
    }

    //上浮
    swim () {
        let curIdx = this.heapArray.length - 1
        while (curIdx > 0) {
            let fatherIdx = Math.floor((curIdx - 1) / 2) 
            if (this.heapArray[curIdx] < this.heapArray[fatherIdx]) {
                [this.heapArray[curIdx], this.heapArray[fatherIdx]] = [this.heapArray[fatherIdx], this.heapArray[curIdx]]
                curIdx = fatherIdx
            } else {
                return
            }
        }
    }

    pop () {
        if (this.heapArray.length === 0) {
            return null
        } else if (this.heapArray.length === 1) {
            return this.heapArray.pop()
        }
        let top = this.heapArray[0]
        this.heapArray[0] = this.heapArray.pop()
        this.sink()
        return top
    }

    push (val) {
        this.heapArray.push(val)
        this.swim()
    }

}

    let heap = new MinHeap([10, 500, 200, 0, 100, 30, 20, 30, 80, 300]);
    console.log(typeof heap);
    let sortList = []

    while (heap.heapArray.length > 0) {
    sortList.push(heap.heapArray.pop())
    }
    console.log(sortList); // [ 0,  10,  20,  30,  30, 80, 100, 200, 300, 500 ]
    

6.参考文章:blog.csdn.net/TABE_/artic…