PageSourceSearch

https://skylandx.ai/libs/other/BinaryHeap.js

js skylandx.ai collected 2026-10-05 14:40:06 UTC 3,855 bytes, 124 lines download raw bytes

1/*
2** Binary Heap implementation in Javascript
3** From: http://eloquentjavascript.net/1st_edition/appendix2.html
4**
5** Copyright (c) 2007 Marijn Haverbeke, last modified on November 28 2013.
6**
7** Licensed under a Creative Commons attribution-noncommercial license. 
8** All code in this book may also be considered licensed under an MIT license.
9*/
10
11
12
13function BinaryHeap(scoreFunction){
14  this.content = [];
15  this.scoreFunction = scoreFunction;
16}
17
18BinaryHeap.prototype = {
19  push: function(element) {
20    // Add the new element to the end of the array.
21    this.content.push(element);
22    // Allow it to bubble up.
23    this.bubbleUp(this.content.length - 1);
24  },
25
26  pop: function() {
27    // Store the first element so we can return it later.
28    var result = this.content[0];
29    // Get the element at the end of the array.
30    var end = this.content.pop();
31    // If there are any elements left, put the end element at the
32    // start, and let it sink down.
33    if (this.content.length > 0) {
34      this.content[0] = end;
35      this.sinkDown(0);
36    }
37    return result;
38  },
39
40  remove: function(node) {
41    var length = this.content.length;
42    // To remove a value, we must search through the array to find
43    // it.
44    for (var i = 0; i < length; i++) {
45      if (this.content[i] != node) continue;
46      // When it is found, the process seen in 'pop' is repeated
47      // to fill up the hole.
48      var end = this.content.pop();
49      // If the element we popped was the one we needed to remove,
50      // we're done.
51      if (i == length - 1) break;
52      // Otherwise, we replace the removed element with the popped
53      // one, and allow it to float up or sink down as appropriate.
54      this.content[i] = end;
55      this.bubbleUp(i);
56      this.sinkDown(i);
57      break;
58    }
59  },
60
61  size: function() {
62    return this.content.length;
63  },
64
65  bubbleUp: function(n) {
66    // Fetch the element that has to be moved.
67    var element = this.content[n], score = this.scoreFunction(element);
68    // When at 0, an element can not go up any further.
69    while (n > 0) {
70      // Compute the parent element's index, and fetch it.
71      var parentN = Math.floor((n + 1) / 2) - 1,
72      parent = this.content[parentN];
73      // If the parent has a lesser score, things are in order and we
74      // are done.
75      if (score >= this.scoreFunction(parent))
76        break;
77
78      // Otherwise, swap the parent with the current element and
79      // continue.
80      this.content[parentN] = element;
81      this.content[n] = parent;
82      n = parentN;
83    }
84  },
85
86  sinkDown: function(n) {
87    // Look up the target element and its score.
88    var length = this.content.length,
89    element = this.content[n],
90    elemScore = this.scoreFunction(element);
91
92    while(true) {
93      // Compute the indices of the child elements.
94      var child2N = (n + 1) * 2, child1N = child2N - 1;
95      // This is used to store the new position of the element,
96      // if any.
97      var swap = null;
98      // If the first child exists (is inside the array)...
99      if (child1N < length) {
100        // Look it up and compute its score.
101        var child1 = this.content[child1N],
102        child1Score = this.scoreFunction(child1);
103        // If the score is less than our element's, we need to swap.
104        if (child1Score < elemScore)
105          swap = child1N;
106      }
107      // Do the same checks for the other child.
108      if (child2N < length) {
109        var child2 = this.content[child2N],
110        child2Score = this.scoreFunction(child2);
111        if (child2Score < (swap == null ? elemScore : child1Score))
112          swap = child2N;
113      }
114
115      // No need to swap further, we are done.
116      if (swap == null) break;
117
118      // Otherwise, swap and continue.
119      this.content[n] = this.content[swap];
120      this.content[swap] = element;
121      n = swap;
122    }
123  }
124};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.