结构
Javascript没有堆这个数据结构,需要自己实现一个,实现原理是 用一个线性表存储一棵完全二叉树,并依照堆的ADT实现即可:
已知索引为i的结点,求
(1)双亲节点索引? idx/2 || undefined
(2)左孩子节点索引?2*idx+1 || undefined
(3)右孩子节点索引?2*idx+1 || undedined
堆的ADT
(from visualgo)
优先队 (PQ) 抽象数据结构 (ADT) 和普通的队列 ADT 差不多, 但是它多了以下两个主要操作:
insert(x): 放一个新元素 (键值) x 进去优先队 (相同顺序),
y = extract(): 返回已经在优先队里的有着最高优先级(键值)的元素 y 如果存在并列情况,返回先入队的那个。
也就是说像一个正常的 Queue 那样 先进先出(FIFO)
一个小根堆实现如下:
class MinHeap {
constructor() {
this.heap = [];
}
// 获取左叶子索引
getLeftIndex(idx) {
return 2*idx + 1;
}
// 获取右叶子索引
getRightIndex(idx) {
return 2*idx+2;
}
// 获取双亲叶子索引
getParentIndex(idx) {
if(idx === 0) return undefined;
return Math.floor((idx-1)/2);
}
// 建堆操作:插入
insert(val) {
if(val != null) {
this.heap.push(val);
this.siftUp(this.heap.length - 1);
return true;
}
return false;
}
// 建堆操作:上移
siftUp(idx) {
let parent = this.getParentIndex(idx);
while(idx>0 && this.heap[parent] > this.heap[idx]) {
let tmp = this.heap[parent];
this.heap[parent] = this.heap[idx];
this.heap[idx] = tmp;
idx = parent;
parent = this.getParentIndex(idx);
}
}
// 获取堆大小
size() {
return this.heap.length;
}
// 判断是否为空堆
isEmpty() {
return this.size() === 0;
}
// 获取堆顶元素
findMinimum() {
return this.isEmpty() ? undefined : this.heap[0];
}
// 导出操作
extract() {
if(this.isEmpty()) return undefined;
if(this.size() === 1) return this.heap.shift();
const removeValue = this.heap.shift();
this.siftDown(0);
return removeValue;
}
// 调整堆:下移
siftDown(idx) {
let element = idx;
const left = this.getLeftIndex(idx);
const right = this.getRightIndex(idx);
const size = this.size();
if(left < size && this.heap[element] > this.heap[left]) element = left;
if(right < size && this.heap[element] > this.heap[right]) element = right;
if(idx != element) {
let tmp = this.heap[idx];
this.heap[idx] = this.heap[element];
this.heap[element] = tmp;
this.siftDown(element);
}
}
}
使用
(1)1834 单线程 CPU
(2)40. 最小的k个数
(3)215. 数组中的第K个最大元素
(4)42. 接雨水
(5)“Top” k 题型总结ing:
“Top” k - 1: leetcode 215
“Top” k - 2: 面试题17.14
“Top” k - 3: leetcode 973
“Top” k - 4: leetcode 1167
“Top” k - 5: leetcode 347
“Top” k - 6: leetcode 451
(6)767 重构字符串