1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| function BinaryHeap(scoreFunction) { this.content = [] this.scoreFunction = scoreFunction }
BinaryHeap.prototype = { push: function (element) { this.content.push(element) this.bubbleUp(this.content.length - 1) },
pop: function () { var result = this.content[0] var end = this.content.pop() if (this.content.length > 0) { this.content[0] = end this.sinkDown(0) } return result },
remove: function (node) { var length = this.content.length for (var i = 0; i < length; i++) { if (this.content[i] != node) continue var end = this.content.pop() if (i == length - 1) break this.content[i] = end this.bubbleUp(i) this.sinkDown(i) break } },
size: function () { return this.content.length },
bubbleUp: function (n) { var element = this.content[n], score = this.scoreFunction(element) while (n > 0) { var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN] if (score >= this.scoreFunction(parent)) break
this.content[parentN] = element this.content[n] = parent n = parentN } },
sinkDown: function (n) { var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element)
while (true) { var child2N = (n + 1) * 2, child1N = child2N - 1 var swap = null if (child1N < length) { var child1 = this.content[child1N], child1Score = this.scoreFunction(child1) if (child1Score < elemScore) swap = child1N } if (child2N < length) { var child2 = this.content[child2N], child2Score = this.scoreFunction(child2) if (child2Score < (swap == null ? elemScore : child1Score)) swap = child2N }
if (swap == null) break
this.content[n] = this.content[swap] this.content[swap] = element n = swap } }, }
|