fix: small improvement on binary heap implementation (#9992)

This commit is contained in:
Yago Dórea
2025-09-30 12:09:20 -03:00
committed by GitHub
parent f1b097ad06
commit 7c41944856

View File

@@ -5,17 +5,18 @@ export class BinaryHeap<T> {
sinkDown(idx: number) { sinkDown(idx: number) {
const node = this.content[idx]; const node = this.content[idx];
const nodeScore = this.scoreFunction(node);
while (idx > 0) { while (idx > 0) {
const parentN = ((idx + 1) >> 1) - 1; const parentN = ((idx + 1) >> 1) - 1;
const parent = this.content[parentN]; const parent = this.content[parentN];
if (this.scoreFunction(node) < this.scoreFunction(parent)) { if (nodeScore < this.scoreFunction(parent)) {
this.content[parentN] = node;
this.content[idx] = parent; this.content[idx] = parent;
idx = parentN; // TODO: Optimize idx = parentN; // TODO: Optimize
} else { } else {
break; break;
} }
} }
this.content[idx] = node;
} }
bubbleUp(idx: number) { bubbleUp(idx: number) {
@@ -24,35 +25,39 @@ export class BinaryHeap<T> {
const score = this.scoreFunction(node); const score = this.scoreFunction(node);
while (true) { while (true) {
const child2N = (idx + 1) << 1; const child1N = ((idx + 1) << 1) - 1;
const child1N = child2N - 1; const child2N = child1N + 1;
let swap = null; let smallestIdx = idx;
let child1Score = 0; let smallestScore = score;
// Check left child
if (child1N < length) { if (child1N < length) {
const child1 = this.content[child1N]; const child1Score = this.scoreFunction(this.content[child1N]);
child1Score = this.scoreFunction(child1); if (child1Score < smallestScore) {
if (child1Score < score) { smallestIdx = child1N;
swap = child1N; smallestScore = child1Score;
} }
} }
// Check right child
if (child2N < length) { if (child2N < length) {
const child2 = this.content[child2N]; const child2Score = this.scoreFunction(this.content[child2N]);
const child2Score = this.scoreFunction(child2); if (child2Score < smallestScore) {
if (child2Score < (swap === null ? score : child1Score)) { smallestIdx = child2N;
swap = child2N;
} }
} }
if (swap !== null) { if (smallestIdx === idx) {
this.content[idx] = this.content[swap];
this.content[swap] = node;
idx = swap; // TODO: Optimize
} else {
break; break;
} }
// Move the smaller child up, continue finding position for node
this.content[idx] = this.content[smallestIdx];
idx = smallestIdx;
} }
// Place node in its final position
this.content[idx] = node;
} }
push(node: T) { push(node: T) {