pisces-data-structure
Version:
122 lines (89 loc) • 3.03 kB
text/typescript
/**
* 堆结构(二叉堆)
*/
import { THeapType, IHeap } from "../../types";
class Heap<T = any> implements IHeap<T> {
private data: T[] = [];
private length = 0;
private type: THeapType = 'max';
private swapElement(i: number, j: number) {
[this.data[i], this.data[j]] = [this.data[j], this.data[i]];
}
private compareNode(i: number, j: number) {
if (this.type === 'max') {
return this.data[i] >= this.data[j];
} else {
return this.data[i] <= this.data[j];
}
}
private percolateUp() {
let _currentIndex = this.length - 1;
while (_currentIndex > 0) {
let _parentIndex = Math.floor((_currentIndex - 1) / 2);
if (this.compareNode(_parentIndex, _currentIndex)) {
break;
}
this.swapElement(_currentIndex, _parentIndex);
_currentIndex = _parentIndex;
}
}
private percolateDown(startIndex = 0) {
let _currentIndex = startIndex;
while ((_currentIndex * 2 + 1) < this.length) {
const _leftChildIndex = _currentIndex * 2 + 1;
const _rightChildIndex = _currentIndex * 2 + 2;
let _targetChildIndex = _leftChildIndex;
if (_rightChildIndex < this.length && this.compareNode(_rightChildIndex, _leftChildIndex)) {
_targetChildIndex = _rightChildIndex;
}
if (this.compareNode(_currentIndex, _targetChildIndex)) {
break;
}
this.swapElement(_currentIndex, _targetChildIndex);
_currentIndex = _targetChildIndex;
}
}
constructor(originalArr: T[] = [], type?: THeapType) {
if (type) this.type = type;
if (originalArr.length > 0) this.buildHeap(originalArr);
}
public insert(element: T) {
this.data.push(element);
this.length++;
this.percolateUp();
}
public extract(): T | undefined {
if (this.length === 0) {
return undefined;
} else if (this.length === 1) {
this.length--;
return this.data.pop()!;
} else {
const _topValue = this.data[0];
this.data[0] = this.data.pop()!;
this.length--;
this.percolateDown();
return _topValue;
}
}
public peek(): T | undefined {
return this.data[0];
}
public isEmpty(): boolean {
return this.length === 0;
}
public get size() {
return this.length;
}
public buildHeap(list: T[]) {
this.data = list;
this.length = list.length;
const _startIndex = Math.floor(this.length / 2 - 1);
for (let _index = _startIndex; _index >= 0; _index--) {
this.percolateDown(_index);
}
}
}
export {
Heap,
};