堆的概述
-
堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。
export class Heap<T>{
public heap: Array<T>;
private type: string;
constructor(type?: string) {
this.type = type == 'MaxHeap' ? 'MaxHeap' : 'MinHeap';
this.heap = [];
}
private swap(i, j): void {
let t = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = t;
}
protected shiftUp(index: number): void {
if (index == 0) return;
const parentIndex: number = Math.floor((index - 1) / 2);
if (this.type == 'MaxHeap') {
if (this.heap[parentIndex] < this.heap[index]) {
this.swap(parentIndex, index);
this.shiftUp(parentIndex);
}
} else {
if (this.heap[parentIndex] > this.heap[index]) {
this.swap(parentIndex, index);
this.shiftUp(parentIndex);
}
}
}
public insert(value: T): Heap<T> {
this.heap.push(value);
this.shiftUp(this.heap.length - 1);
return this;
}
private shiftDown(index: number): void {
const leftIndex = index * 2 + 1;
const rightIndex = index * 2 + 2;
if (this.type == 'MaxHeap') {
if (this.heap[leftIndex] > this.heap[index]) {
this.swap(leftIndex, index);
this.shiftDown(leftIndex);
}
if (this.heap[rightIndex] > this.heap[index]) {
this.swap(rightIndex, index);
this.shiftDown(rightIndex);
}
} else {
if (this.heap[leftIndex] < this.heap[index]) {
this.swap(leftIndex, index);
this.shiftDown(index);
}
if (this.heap[rightIndex] < this.heap[index]) {
this.swap(rightIndex, index);
this.shiftDown(index);
}
}
}
public pop(): T {
let value: T = this.heap[0];
this.heap[0] = this.heap.pop();
this.shiftDown(0);
return value;
}
public linkPop(): Heap<T> {
this.heap[0] = this.heap.pop();
this.shiftDown(0);
return this;
}
public sort(): Heap<T> {
let arr: Array<T> = [];
let len = this.heap.length;
for (let i = 0; i < len; ++i) {
arr.push(this.pop());
}
this.heap = arr;
return this;
}
public makeHeap(arr?: Array<T>): Heap<T> {
if (arr) {
this.heap = arr;
}
let len = this.heap.length;
let reset = [...this.heap];
this.heap = [];
for (let i = 0; i < len; ++i) {
this.insert(reset.pop());
}
return this;
}
public isHeap(): boolean {
if (this.type == 'MaxHeap') {
for (let i = 1; i <= (this.heap.length - 2) / 2; i++) {
if (this.heap[Math.floor((i - 1) / 2)] < this.heap[2 * i + 1] || this.heap[i] < this.heap[2 * i + 2]) {
return false;
}
}
} else {
for (let i = 1; i <= (this.heap.length - 2) / 2; i++) {
if (this.heap[Math.floor((i - 1) / 2)] > this.heap[2 * i + 1] || this.heap[i] > this.heap[2 * i + 2]) {
return false;
}
}
}
return true;
}
public changeHeap(type: string): string {
this.type = type == 'MaxHeap' ? 'MaxHeap' : 'MinHeap';
this.makeHeap();
return this.type;
}
public heapType(): string {
return this.type;
}
};
type intArray = Array<number>;
let arr: intArray = [1, 2, 3, 45, 456, 23, 324, 24, 34, 14, 56, 25, 75, 36];
let str = ['asd', '123', 'asdd', '345', 'zxc', 'zy'];
let h1:Heap<number> = new Heap();
h1.insert(1).insert(2).insert(3).insert(4).insert(5).insert(6).insert(7).insert(8).sort();
console.log(h1.heap);
let h2:Heap<string>=new Heap();
console.log(h2.makeHeap(str).isHeap());
console.log(h2.heapType());
// console.log(h1.heap);
console.log(h2.sort().isHeap());
console.log(h2.changeHeap('MaxHeap'));
console.log(h2.heap);
console.log(h2.heapType());
执行结果
[
1, 2, 3, 6,
5, 4, 7, 8
]
true
MinHeap
true
MaxHeap
[ 'zy', 'zxc', 'asdd', 'asd', '345', '123' ]
MaxHeap