120 lines
3.4 KiB
JavaScript
120 lines
3.4 KiB
JavaScript
|
/**
|
|||
|
* 优先队列的 堆实现
|
|||
|
*/
|
|||
|
class HeapNode {
|
|||
|
constructor(num, item) {
|
|||
|
this.sortNum = num;
|
|||
|
this.content = item;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class Heap {
|
|||
|
constructor(arr = []) {
|
|||
|
this.PRIVATE = {
|
|||
|
swap(arr, i, j) {
|
|||
|
let temp = arr[i]
|
|||
|
arr[i] = arr[j]
|
|||
|
arr[j] = temp
|
|||
|
},
|
|||
|
//从point往下 堆化
|
|||
|
heapify(point = 1) {
|
|||
|
let { swap, store } = this;
|
|||
|
while (true) {
|
|||
|
let lPoint = point * 2;
|
|||
|
let rPoint = point * 2 + 1;
|
|||
|
if (store[lPoint] && store[point].sortNum < store[lPoint].sortNum) {
|
|||
|
swap(store, point, lPoint);
|
|||
|
point = lPoint;
|
|||
|
continue
|
|||
|
}
|
|||
|
if (store[rPoint] && store[point].sortNum < store[rPoint].sortNum) {
|
|||
|
swap(store, point, rPoint);
|
|||
|
point = rPoint;
|
|||
|
continue
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
},
|
|||
|
store: [null].concat(arr)
|
|||
|
}
|
|||
|
//建堆
|
|||
|
//从最后一个非子叶节点遍历
|
|||
|
for (let i = (this.PRIVATE.store.length / 2 | 0); i > 1; i--) {
|
|||
|
this.PRIVATE.heapify(i);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
insert(node) {
|
|||
|
let store = this.PRIVATE.store;
|
|||
|
let HeapUtil = this.PRIVATE;
|
|||
|
store.push(node);
|
|||
|
|
|||
|
let point = store.length - 1;
|
|||
|
let sub = point / 2 | 0;
|
|||
|
while (sub > 0 && store[point].sortNum > store[sub].sortNum) { // 自下往上堆化
|
|||
|
HeapUtil.swap(store, point, sub); // swap()函数作用:交换下标为i和i/2的两个元素
|
|||
|
point = sub;
|
|||
|
sub = sub / 2 | 0;
|
|||
|
}
|
|||
|
}
|
|||
|
getMax() {
|
|||
|
let store = this.PRIVATE.store;
|
|||
|
let point = store.length - 1;
|
|||
|
if (point === 0) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
let HeapUtil = this.PRIVATE;
|
|||
|
//最大与末尾元素交换
|
|||
|
HeapUtil.swap(store, point, 1);
|
|||
|
let max = store.pop();
|
|||
|
HeapUtil.heapify();
|
|||
|
return max;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
function HeapTest() {
|
|||
|
let maxHeap = new Heap();
|
|||
|
console.log('偶数个')
|
|||
|
maxHeap.insert(new HeapNode(2, 'c'))
|
|||
|
maxHeap.insert(new HeapNode(1, 'c'))
|
|||
|
maxHeap.insert(new HeapNode(7, 'a'))
|
|||
|
maxHeap.insert(new HeapNode(4, 'c'))
|
|||
|
console.log('check:', isHeapArr(maxHeap.PRIVATE.store));
|
|||
|
console.log('奇数个')
|
|||
|
maxHeap.insert(new HeapNode(5, 'b'))
|
|||
|
maxHeap.insert(new HeapNode(6, 'c'))
|
|||
|
maxHeap.insert(new HeapNode(10, 'a'))
|
|||
|
console.log('check:', isHeapArr(maxHeap.PRIVATE.store));
|
|||
|
console.log('获取最大值:', maxHeap.getMax());
|
|||
|
console.log('check:', isHeapArr(maxHeap.PRIVATE.store));
|
|||
|
console.log('获取最大值:', maxHeap.getMax());
|
|||
|
console.log('check:', isHeapArr(maxHeap.PRIVATE.store));
|
|||
|
|
|||
|
}
|
|||
|
function createTest() {
|
|||
|
console.log('随机创建测试:')
|
|||
|
let arr = [];
|
|||
|
let i = 0
|
|||
|
while (i <= 10) {
|
|||
|
const num = Math.floor(Math.random() * 100)
|
|||
|
arr.push(new HeapNode(num, i))
|
|||
|
i++
|
|||
|
}
|
|||
|
let heap = new Heap(arr);
|
|||
|
console.log('check:', isHeapArr(heap.PRIVATE.store))
|
|||
|
}
|
|||
|
|
|||
|
function isHeapArr(arr) {
|
|||
|
for (let i = 1; i < arr.length; i++) {
|
|||
|
let p = arr[i];
|
|||
|
let l = arr[i * 2];
|
|||
|
let r = arr[i * 2 + 1];
|
|||
|
if (l > p || r > p) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|