二叉堆主要包含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) { //
对于最大堆,会破坏堆性质的有两种情况:
1、节点 A 小于其中一个子节点,那么 A 就不配做父节点,应该下去,下面那个更大的节点上来做父节点,这就是对 A 进行下沉。
2、如果某个节点 A 比它的父节点大,那么 A 不应该做子节点,应该把父节点换下来,自己去做父节点,这就是对 A 的上浮。
最终 *** 作只会在堆底和堆顶进行(等会讲原因),显然堆底的「错位」元素需要上浮,堆顶的「错位」元素需要下沉。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)