123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- export class BinaryHeap<T>{
- private _content: T[] = [];
- private _scoreFunc: (node: T) => number = null;
- constructor(func: (node: T) => number) {
- this._content = [];
- this._scoreFunc = func;
- }
- insert(element: T) {
-
- this._content.push(element);
-
- this._bubbleUp(this._content.length - 1);
- }
- remove(element: T) {
-
- let length = this._content.length;
- for (let i = 0; i < length; ++i) {
- if (this._content[i] != element) continue;
-
- let end = this._content.pop();
-
- if (i == length - 1) break;
- this._content[i] = end;
-
- this._bubbleUp(i);
- this._sinkDown(i);
- break;
- }
- }
- root() {
-
- let result = this._content[0];
-
- let end = this._content.pop();
-
- if (this._content.length > 0) {
- this._content[0] = end;
- this._sinkDown(0);
- }
- return result;
- }
- size() {
- return this._content.length;
- }
- clear() {
- this._content = [];
- }
- print() {
- console.log(this._content);
- }
- private _sinkDown(idx: number) {
-
- let length = this._content.length;
- let element = this._content[idx];
- let elemScore = this._scoreFunc(element);
- while (true) {
-
- let child2N = (idx + 1) * 2;
- let child1N = child2N - 1;
-
- let swap: number = null;
-
- let child1Score = 0;
- if (child1N < length) {
-
- let child1 = this._content[child1N];
- child1Score = this._scoreFunc(child1);
-
- if (child1Score < elemScore) swap = child1N;
- }
-
- if (child2N < length) {
- let child2 = this._content[child2N];
- let child2Score = this._scoreFunc(child2);
- if (child2Score < (swap == null ? elemScore : child1Score)) swap = child2N;
- }
-
- if (!swap) break;
-
- this._content[idx] = this._content[swap];
- this._content[swap] = element;
- idx = swap;
- }
- }
- private _bubbleUp(idx: number) {
-
- let element = this._content[idx], score = this._scoreFunc(element);
-
- while (idx > 0) {
-
- let parentN = Math.floor((idx + 1) / 2) - 1, parent = this._content[parentN];
-
- if (score >= this._scoreFunc(parent)) break;
-
- this._content[parentN] = element;
- this._content[idx] = parent;
- idx = parentN;
- }
- }
- }
|