Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- export enum HeapType {
- Max, Min
- }
- type HeapifyFn = {
- (i: number): void;
- }
- export class Heap<T> {
- private _heap: T[];
- private readonly _heapType: HeapType;
- private readonly _heapifyFn: HeapifyFn;
- constructor(arr: T[] = [], heapType: HeapType = HeapType.Max) {
- this._heap = [...arr];
- this._heapType = heapType;
- if (heapType === HeapType.Max)
- this._heapifyFn = this.maxHeapify;
- else
- this._heapifyFn = this.minHeapify;
- this.buildHeap(this._heapifyFn);
- }
- private maxHeapify = (i: number = 0): void => {
- const leftChildIndex = 2 * i + 1;
- const rightChildIndex = 2 * i + 2;
- let indexOfLargest = i;
- if ((leftChildIndex < this._heap.length) &&
- (this._heap[leftChildIndex] > this._heap[indexOfLargest])
- )
- indexOfLargest = leftChildIndex;
- if ((rightChildIndex < this._heap.length) &&
- (this._heap[rightChildIndex] > this._heap[indexOfLargest])
- )
- indexOfLargest = rightChildIndex;
- if (indexOfLargest != i) {
- const temp = this._heap[i];
- this._heap[i] = this._heap[indexOfLargest];
- this._heap[indexOfLargest] = temp;
- this.maxHeapify(indexOfLargest);
- }
- }
- private minHeapify = (i: number = 0): void => {
- const leftChildIndex = 2 * i + 1;
- const rightChildIndex = 2 * i + 2;
- let indexOfSmallest = i;
- if ((leftChildIndex < this._heap.length) &&
- (this._heap[leftChildIndex] < this._heap[indexOfSmallest])
- )
- indexOfSmallest = leftChildIndex;
- if ((rightChildIndex < this._heap.length) &&
- (this._heap[rightChildIndex] < this._heap[indexOfSmallest])
- )
- indexOfSmallest = rightChildIndex;
- if (indexOfSmallest != i) {
- const temp = this._heap[i];
- this._heap[i] = this._heap[indexOfSmallest];
- this._heap[indexOfSmallest] = temp;
- this.minHeapify(indexOfSmallest);
- }
- }
- private buildHeap = (heapify: HeapifyFn): void => {
- const heapSize = this._heap.length;
- if (heapSize > 1) {
- const lastParent = ~~(heapSize / 2) - 1;
- for (let i = lastParent; i >= 0; --i) {
- heapify(i);
- }
- }
- }
- public insert = (data: T): void => {
- this._heap.push(data);
- let dataIndex = this._heap.length - 1;
- let parentIndex = ~~((dataIndex - 1) / 2);
- if (this._heapType === HeapType.Max) {
- while (parentIndex >= 0 && this._heap[dataIndex] > this._heap[parentIndex]) {
- const temp = this._heap[parentIndex];
- this._heap[parentIndex] = this._heap[dataIndex];
- this._heap[dataIndex] = temp;
- dataIndex = parentIndex;
- parentIndex = ~~((dataIndex - 1) / 2);
- }
- }
- else if (this._heapType === HeapType.Min) {
- while (parentIndex >= 0 && this._heap[dataIndex] < this._heap[parentIndex]) {
- const temp = this._heap[parentIndex];
- this._heap[parentIndex] = this._heap[dataIndex];
- this._heap[dataIndex] = temp;
- dataIndex = parentIndex;
- parentIndex = ~~((dataIndex - 1) / 2);
- }
- }
- }
- public getRoot = (): T | null => this._heap.length ? this._heap[0] : null;
- public extractRoot = (): T | null => {
- const root = this._heap.shift();
- if (root) {
- const lastEl = this._heap.pop();
- if (lastEl) {
- this._heap.unshift(lastEl);
- this._heapifyFn(0);
- }
- return root;
- }
- else return null;
- }
- public sort = (): T[] => {
- const heapCopy: T[] = [...this._heap];
- const sortedArr: T[] = [];
- while (this.getRoot()) {
- const root = this.extractRoot();
- if (root) sortedArr.push(root);
- }
- this._heap = heapCopy;
- return sortedArr;
- }
- }
Add Comment
Please, Sign In to add comment