堆与堆排序(heap sort)

什么是堆?

堆是一个完全二叉树的数据结构!

image.png

普通队列 优先队列(堆)
从头出队列 从头弹出
从尾入队列 从尾插入
先进先出 每次出队权值(最大值/最小值)
数组实现 数组实现(数据结构上看成是堆)
堆的用处
堆怎么实现?

之前实现的最小堆可回看

首先我们要找到左右子节点和父节点的关系。

下图是当根节点为编号0时,各子节点的编号示意图 image.png

// 已知父节点parentIndex 求左右子节点
leftIndex = parentIndex * 2 + 1
rightIndex = parentIndex * 2 + 2

// 已知子节点求父节点
leftIndex or rightIndex 都看成 childIndex
parentIndex = (childIndex - 1) >> 1 // 无论左右取整后得到都是一样的
复制代码

然后我们根据节点关系构建堆(一般使用大顶堆)

class Heap{
    constructor(){
        this.data = [] //初始化数组存储
        this.cnt = 0 // 长度
    }
    //  
    size(){
        return this.cnt 
    }
    // 顶部元素
    top(){
        if(this.size()==0)return -1
        return this.data[0]
    }
    swap(i,j){
        [this.data[i], this.data[j]] =[this.data[j], this.data[i]]
    }
    // 插入元素
    push(val){
        this.data[this.cnt ++] = val
        this.liftUp(this.cnt-1) //向上调整
    }
    // 
    liftUp(ind){
        // 和父节点做比较 , 如果比父节点大就和父节点交换位置
        let parentIndex = (ind - 1) >> 1
        while(ind && this.data[ind] > this.data[parentIndex]){
            parentIndex = (ind - 1) >> 1
            this.swap(ind, parentIndex)
            ind = parentIndex
        }
    }
    // 弹出元素
    pop(){
        this.data[0] = this.data.pop()  // 将末尾元素放到头部来 向下调整
        // 如果需要堆排序 直接将上面代码改为
        // this.swap(0, cnt-1)
        this.cnt -=1
        this.liftDown(0)
    }
    liftDown(ind){
        // 和子节点比较如果小于子节点向下调整
        let n = this.cnt - 1
        while(leftChildIndex <= n){
            let temp = ind
            let leftChildIndex = ind * 2 + 1
            let rightChildIndex = ind * 2 + 2
            if(this.data[ind] < this.data[leftChildIndex] ) temp = leftChildIndex// leftChildIndex<=n 说明有左子节点
            if(rightIndex<=n && this.data[ind]< this.data[rightChildIndex]) temp = rightChildIndex // rightChildIndex<=n说明有右子节点
            if(temp == ind) break ; // 说明不需要调整
            this.swap(ind ,temp) // 需要调整互换
            ind = temp
        }
    }
}


复制代码

Acho que você gosta

Origin juejin.im/post/7040730725485641759
Recomendado
Clasificación