UNPKG

pisces-data-structure

Version:

122 lines (89 loc) 3.03 kB
/** * 堆结构(二叉堆) */ 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, };