Create BinaryHeap class - Node.js Data Structure

Node.js examples for Data Structure:Heap

Description

Create BinaryHeap class

Demo Code


// make sure we have the array functions we need
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item) {
    var len = this.length;
    var from = Number(argument[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0) from += len;
    for (; from < len; from++) {
      if (from in this && this[from] == item) return from;
    }//from  w  w w  .j  av  a 2 s .c  o m
    return -1;
  };
}
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = (from < 0) ? this.length + from : from;
  return this.push.apply(this, rest);
}

// binary heap
function BinaryHeap(scoreFunction) {
  this.content = [];
  this.scoreFunction = scoreFunction;
}
BinaryHeap.prototype = {
  push: function(el) {
    this.content.push(el);
    this.sinkDown(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.bubbleUp(0);
    }
    return result;
  },
  remove: function(node) {
    var len = this.content.length;
    for (var i = 0; i < len; i++) {
      if (this.content[i] == node) {
        var end = this.content.pop();
        if (i != len - 1) {
          this.content[i] = end;
          if (this.scoreFunction(end) < this.scoreFunction(node))
            this.sinkDown(i);
          else
            this.bubbleUp(i);
        }
        return;
      }
    }
    throw new Error('Node not found');
  },
  size: function() {
    return this.content.length;
  },
  rescoreElement: function(node) {
    this.sinkDown(this.content.indexOf(node));
  },
  sinkDown: function(n) {
    var el = this.content[n];
    while (n > 0) {
      var parentN = Math.floor((n + 1) / 2) - 1;
      var parent = this.content[parentN];
      if (this.scoreFunction(el) < this.scoreFunction(parent)) {
        this.content[parentN] = el;
        this.content[n] = parent;
        n = parentN;
      } else {
        break;
      }
    }
  },
  bubbleUp: function(n) {
    var length = this.content.length;
    var el = this.content[n];
    var elScore = this.scoreFunction(el);
    while (true) {
      var child2N = (n + 1) * 2;
      var child1N = child2N - 1;
      var swap = null;
      if (child1N < length) {
        var child1 = this.content[child1N];
        var child1Score = this.scoreFunction(child1);
        if (child1Score < elScore)
          swap = child1N;
      }
      if (child2N < length) {
        var child2 = this.content[child2N];
        var child2Score = this.scoreFunction(child2);
        if (child2Score < ((swap == null) ? elScore : child1Score))
          swap = child2N;
      }
      if (swap != null) {
        this.content[n] = this.content[swap];
        this.content[swap] = el;
        n = swap;
      } else {
        break;
      }
    }
  }
}

Related Tutorials