堆数据结构,大根堆小根堆
/**
- 大根堆特特点
- 1.根节点大于左右子树的节点
- 2.大根堆是一个完全二叉树
- 大根堆父子节点之间的关系,对于节点i
- 1.父节点:f=Math.floor((i-1)/2)
- 2.左子节点:f=2*i+1
- 3.右子节点:f=2*i+2 */
abstract class Heap {
heap = [];
constructor(heap: number[] = []) {
this.heap = heap;
for (let i = 1; i < heap.length; i++) {
this.insertFromEnd(i);
}
}
//插入
insert(ele) {
this.heap.push(ele);
this.insertFromEnd(this.heap.length - 1);
}
//删除
remove() {
const res = this.heap[0];
if (res === undefined) {
return res;
}
if (this.heap.length === 1) {
return this.heap.pop();
}
this.heap[0] = this.heap.pop();
for (
let i = 0, temp = 2 * i + 1;
temp < this.heap.length;
temp = 2 * i + 1
) {
let nextI = temp;
if (temp + 1 < this.heap.length && this.testFlag(temp + 1, temp)) {
nextI = temp + 1;
}
if (this.testFlag(nextI, i)) {
this.swap(i, nextI);
} else {
break;
}
i = nextI;
}
return res;
}
//从最后一个节点插入
abstract insertFromEnd(i: number): void;
abstract testFlag(i, j): boolean;
//执行交换
swap(i, j) {
const temp = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = temp;
}
//获取栈顶元素
getHeapTop() {
return this.heap[0];
}
}
class BigHeap extends Heap {
constructor(array: number[] = []) {
super([...array]);
console.log(this);
}
testFlag(i, j) {
return this.heap[i] > this.heap[j];
}
insertFromEnd(i) {
for (
let temp = Math.floor((i - 1) / 2);
this.heap[i] > this.heap[temp];
i = temp, temp = Math.floor((i - 1) / 2)
) {
this.swap(i, temp);
}
}
}
class SmallHeap extends Heap {
constructor(array: number[]) {
super([...array]);
console.log(this);
}
testFlag(i, j) {
return this.heap[i] < this.heap[j];
}
insertFromEnd(i) {
let pi = Math.floor((i - 1) / 2);
while (this.heap[pi] > this.heap[i]) {
this.swap(i, pi);
i = pi;
pi = Math.floor((i - 1) / 2);
}
}
}
利用堆解决问题
215. 数组中的第K个最大元素
function findKthLargest(nums: number[], k: number): number {
const bigHeap = new BigHeap(nums);
let i = 0;
let res = -1;
while (i < k) {
res = bigHeap.remove();
i++;
}
if (i === k) {
return res;
}
return -1;
}
const res = findKthLargest([], 10);
求地k个丑数
function nthUglyNumber(n: number): number {
if (n === 1) {
return 1;
}
const set = new Set([1]);
const smallHeap = new SmallHeap([1]);
for (let i = 1; i < n; i++) {
const sm = smallHeap.remove();
for (let j = 2; j <= 5; j++) {
const newItem = j * sm;
if (!set.has(newItem)) {
set.add(newItem);
smallHeap.insert(newItem);
}
}
}
return smallHeap.remove();
}