js处理二叉堆

二叉堆主要包含2个应用::
1、排序方法「堆排序」
2、数据结构 优先级队列

二叉堆是一个存储在数组里的完全二叉树
主要操作是插入和删除。
插入是先插到最后,然后上浮到正确位置;
删除是和堆底元素调换位置后再删除,然后下沉到正确位置。

const parent = (root) => {
	return root/2
}
const left = (root) => {
	return root/2
}
const rigth = (root) => {
	return root/2+1
}

二叉堆还分为最大堆和最小堆。
最大堆的性质是:每个节点都大于等于它的两个子节点。类似的,
最小堆的性质是:每个节点都小于等于它的子节点。

优先级队列

插入insert或者删除delMax元素的时候,元素会自动排序,这底层的原理就是二叉堆的操作。

class primaryQueue {
    constructor() {
        this.heap = []
        this.heap[0] = 0
    }
    swap(i, j) {
        let temp = this.heap[i]
        this.heap[i] = this.heap[j]
        this.heap[j] = temp
    }
    getParentIdx(root) {
        return Math.floor(root/2)
    }
    getLeftIdx(root) {
        return root*2
    }
    getRightIdx(root) {
        return root*2+1
    }
    swim(x) {
        while(x > 1) { // x=1是根顶
            let parent = this.getParentIdx(x) 
            if(this.heap[parent].val > this.heap[x].val) { // 小根堆
                this.swap(parent, x)
                x = this.getParentIdx(x) 
            }else {
                break
            }
        }
    }
    sink(x) { // 下沉
        while(this.heap[this.getLeftIdx(x)]) { // 叶子节点
            let left = this.getLeftIdx(x) // 索引
            let right = this.getRightIdx(x) // 索引
            if(this.heap[right] && this.heap[left].val > this.heap[right].val) {
                left = right
            }
            if(this.heap[x].val < this.heap[left].val) { // <max(a, b)
                break
            }
            this.swap(left, x)
            x= left
        }
    }
    insert(val) {
        this.heap.push(val)
        this.swim(this.heap.length-1) // 插入堆底,堆底元素需要上浮
    }
    delMin(x) { // 删除最小节点-“最小堆”,交换和堆顶的元素,sink
        const top = this.heap[1]
        const len = this.heap.length-1
        this.swap(1, len)
        this.heap.length--
        this.sink(1)
        return top
    }
    getMin() {
        return this.heap[1]
    }
    getSize() {
        return this.heap.length
    }

}

对于最大堆,会破坏堆性质的有两种情况:

1、节点 A 小于其中一个子节点,那么 A 就不配做父节点,应该下去,下面那个更大的节点上来做父节点,这就是对 A 进行下沉

2、如果某个节点 A 比它的父节点大,那么 A 不应该做子节点,应该把父节点换下来,自己去做父节点,这就是对 A 的上浮。

最终操作只会在堆底和堆顶进行(等会讲原因),显然堆底的「错位」元素需要上浮,堆顶的「错位」元素需要下沉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值