📅  最后修改于: 2023-12-03 15:28:59.627000             🧑  作者: Mango
在算法中,堆是一种经常用到的数据结构。堆通常是一个可以被看做一棵树的数组对象。
在堆的这种数据结构中,每个结点都有一个值。通常我们所说的堆的基本性质是:在堆中的任意一个节点,它的子节点的值都大于等于(或小于等于)它的值。
高度为 h 的堆中元素的最小和最大数量可以通过以下公式计算:
最小值数量: 2^h
最大值数量: 2^(h+1)-1
对于 TypeScript 实现堆,可以使用数组来表示堆,而不是使用链表,因为数组的访问速度比链接快得多。我们可以使用以下 TypeScript 代码创建一个最小化堆:
class MinHeap {
private heap: number[];
constructor() {
this.heap = [];
}
public get size(): number {
return this.heap.length;
}
public get isEmpty(): boolean {
return this.size === 0;
}
private getLeftChildIndex(parentIndex: number): number {
return 2 * parentIndex + 1;
}
private getRightChildIndex(parentIndex: number): number {
return 2 * parentIndex + 2;
}
private getParentIndex(childIndex: number): number {
return Math.floor((childIndex - 1) / 2);
}
private siftUp(): void {
let index = this.size - 1;
while (index > 0) {
const parentIndex = this.getParentIndex(index);
if (this.heap[parentIndex] > this.heap[index]) {
[this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];
index = parentIndex;
} else {
break;
}
}
}
private siftDown(): void {
let index = 0;
while (this.getLeftChildIndex(index) < this.size) {
const leftChildIndex = this.getLeftChildIndex(index);
const rightChildIndex = this.getRightChildIndex(index);
const smallerChildIndex = rightChildIndex < this.size && this.heap[rightChildIndex] < this.heap[leftChildIndex]
? rightChildIndex
: leftChildIndex;
if (this.heap[smallerChildIndex] < this.heap[index]) {
[this.heap[smallerChildIndex], this.heap[index]] = [this.heap[index], this.heap[smallerChildIndex]];
index = smallerChildIndex;
} else {
break;
}
}
}
public peek(): number {
if (this.isEmpty) {
throw new Error('Heap is empty');
}
return this.heap[0];
}
public insert(value: number): void {
this.heap.push(value);
this.siftUp();
}
public remove(): number {
if (this.isEmpty) {
throw new Error('Heap is empty');
}
const minValue = this.heap[0];
const lastValue = this.heap.pop()!;
if (!this.isEmpty) {
this.heap[0] = lastValue;
this.siftDown();
}
return minValue;
}
}
以上代码展示了如何使用 TypeScript 实现堆数据结构,在最小堆的情况下,它是按升序排列元素的。我们可以使用相同的代码来创建最大堆,只需要在siftDown方法中反转childIndex和rightChildIndex,比如:
private siftDown(): void {
let index = 0;
while (this.getLeftChildIndex(index) < this.size) {
const leftChildIndex = this.getLeftChildIndex(index);
const rightChildIndex = this.getRightChildIndex(index);
const largerChildIndex = rightChildIndex < this.size && this.heap[rightChildIndex] > this.heap[leftChildIndex]
? rightChildIndex
: leftChildIndex;
if (this.heap[largerChildIndex] > this.heap[index]) {
[this.heap[largerChildIndex], this.heap[index]] = [this.heap[index], this.heap[largerChildIndex]];
index = largerChildIndex;
} else {
break;
}
}
}
在创建完堆之后,我们就可以使用以下代码计算高度为 h 的堆中元素的最小和最大数量,并输出结果:
function getMinMaxCount(h: number): [number, number] {
const minCount = 2 ** h;
const maxCount = 2 ** (h + 1) - 1;
return [minCount, maxCount];
}
const [minCount, maxCount] = getMinMaxCount(3);
console.log(`高度为3的堆中元素的最小数量:${minCount}`); // 输出:8
console.log(`高度为3的堆中元素的最大数量:${maxCount}`); // 输出:15
以上代码使用了函数getMinMaxCount计算高度为 h 的堆中元素的最小和最大数量,并将其存储在minCount和maxCount中,并在控制台上输出结果。
Markdown代码片段如下:
# TypeScript - 高度为 h 的堆中元素的最小和最大数量
在算法中,堆是一种经常用到的数据结构。堆通常是一个可以被看做一棵树的数组对象。
在堆的这种数据结构中,每个结点都有一个值。通常我们所说的堆的基本性质是:在堆中的任意一个节点,它的子节点的值都大于等于(或小于等于)它的值。
高度为 h 的堆中元素的最小和最大数量可以通过以下公式计算:
最小值数量: 2^h
最大值数量: 2^(h+1)-1
对于 TypeScript 实现堆,可以使用数组来表示堆,而不是使用链表,因为数组的访问速度比链接快得多。我们可以使用以下 TypeScript 代码创建一个最小化堆:
```typescript
class MinHeap {
// 实现细节
}
以上代码展示了如何使用 TypeScript 实现堆数据结构,在最小堆的情况下,它是按升序排列元素的。我们可以使用相同的代码来创建最大堆,只需要在siftDown方法中反转childIndex和rightChildIndex。
在创建完堆之后,我们就可以使用以下代码计算高度为 h 的堆中元素的最小和最大数量,并输出结果:
function getMinMaxCount(h: number): [number, number] {
// 实现细节
}
const [minCount, maxCount] = getMinMaxCount(3);
console.log(`高度为3的堆中元素的最小数量:${minCount}`); // 输出:8
console.log(`高度为3的堆中元素的最大数量:${maxCount}`); // 输出:15
以上代码使用了函数getMinMaxCount计算高度为 h 的堆中元素的最小和最大数量,并将其存储在minCount和maxCount中,并在控制台上输出结果。