Search code examples
javascriptalgorithmheapsortmax-heap

Heapsort not working in Javascript


I am trying to implement heapsort in Javascript, but there is a undefined element at array.length - 2 and the element at index 0 is unsorted. Here is the code:

var heapSort = function(array) {
  var swap = function(array, firstIndex, secondIndex) {
    var temp = array[firstIndex];
    array[firstIndex] = array[secondIndex];
    array[secondIndex] = temp;
  };
  var maxHeap = function(array, i) {
    var l = 2 * i;
    var r = l + 1;
    var largest;
    if (l <= array.heapSize && array[l] > array[i]) {
      largest = l;
    } else {
      largest = i;
    }
    if (r <= array.heapSize && array[r] > array[largest]) {
      largest = r;
    }
    if (largest != i) {
      swap(array, i, largest);
      maxHeap(array, largest);
    }
  };
  var buildHeap = function(array) {
    array.heapSize = array.length;
    for (var i = Math.floor(array.length / 2); i >= 1; i--) {
      maxHeap(array, i);
    }
  };
  buildHeap(array);
  for (var i = array.length; i >= 2; i--) {
    swap(array, 1, i);
    array.heapSize--;
    maxHeap(array, 1);
  }
};
var a = [55, 67, 10, 34, 25, 523, 1, -2];
heapSort(a);
document.getElementById("getHeapSort").innerHTML = a;
* {
  font-family: Arial, sans-serif;
}
<p id="getHeapSort"></p>

I figured that array[i] == undefined when i = array.length. I tried fixing this (setting i = array.length - 1), but the array came out in an entirely different order. I also figured that 0 was never swapped because i is always greater than 0. Again, I tried, and the array came out in a entirely different order.


Solution

  • You were using 1-based indexing instead of 0-based indexing in JavaScript. I also added a trace for your convenience.

    Try this:

    var heapSort = function(array) {
      var swap = function(array, firstIndex, secondIndex) {
        var temp = array[firstIndex];
        array[firstIndex] = array[secondIndex];
        array[secondIndex] = temp;
      };
      var maxHeap = function(array, i) {
        var l = 2 * i;
        var r = l + 1;
        var largest;
        if (l < array.heapSize && array[l] > array[i]) {
          largest = l;
        } else {
          largest = i;
        }
        if (r < array.heapSize && array[r] > array[largest]) {
          largest = r;
        }
        if (largest != i) {
          swap(array, i, largest);
          maxHeap(array, largest);
        }
      };
      var buildHeap = function(array) {
        array.heapSize = array.length;
        for (var i = Math.floor(array.length / 2); i >= 0; i--) {
          maxHeap(array, i);
        }
      };
      buildHeap(array);
      for (var i = array.length-1; i >= 1; i--) {
        swap(array, 0, i);
        array.heapSize--;
        maxHeap(array, 0);
    
        document.getElementById("getHeapSort").innerHTML = document.getElementById("getHeapSort").innerHTML + a + "<br>";
      }
    };
    var a = [55, 67, 10, 34, 25, 523, 1, -2];
    document.getElementById("getHeapSort").innerHTML = a + "<br>";
    heapSort(a);
    

    Here is a JFiddle: http://jsfiddle.net/mbL5enL5/1/