Search code examples
javascriptalgorithmheapsort

Heapsort algorithm, putting the smallest element at the end


I have implemented a set of sorting algorithms in javascript, for training purposes. My implementations has been successfull in sorting integer and single-character string arrays, except for the heapsort.

My implementation sorts the array correctly, with the exception of putting the smallest number to the end, when returning the sorted array.

I'm not a CS student/graduate, nor I have got a lot of programming background. I'm learning via read/try/fail method, and I couldn't get to make this work correctly.

I'll put the code and it's results below this paragraph. Lastly, I want to add that I'm taking the pseudocode at this Wikipedia article as the reference of my implementation.

function heapSort(intl)
{
    var l   = intl.length,
        end = l - 1,
        swap;
    intl = _heapify(intl,l);

    while(end>0)
    {
        swap      = intl[0];
        intl[0]   = intl[end];
        intl[end] = swap;
        --end;
        intl = _siftDown(intl, 0, end);
    }

    return intl;
}


function _heapify(intl, l)
{
    var start = (l - 2) / 2;
    while(start >= 0)
    {
        intl = _siftDown(intl, start, l-1);
        --start;
    }
    return intl;
}

function _siftDown(intl, start, end)
{
    var root = start,
        child, swap, swapr;
    while(root*2+1 <= end)
    {
        child = root * 2 + 1;
        swap = root;
        if(intl[swap] < intl[child])
            swap = child;
        if(child+1 <= end && intl[swap]<intl[child+1])
            swap = child + 1;
        if(swap!=root)
        {
            swap       = intl[root];
            intl[root] = intl[swap];
            intl[swap] = swap;
            root       = swap;
        }else
        {
            return intl;
        }
    }
    return intl;
}


x =
[24,5,896,624,437,5,6,4,37,45,654];
y =
["a","b","r","s","t","e","q","u","q"];

console.log(heapSort(x),"\n",heapSort(y));

Running the code via nodejs:

$ node sort.js
[ 5, 5, 6, 24, 37, 45, 437, 624, 654, 896, 4 ]
[ 'b', 'e', 'q', 'q', 'r', 's', 't', 'u', 'a' ]

I've tried to find where the error is, with altering the code, but I couldn't find it. Can anyone tell where the problem is? Thanks in advance.


Solution

  • I have seen 2 errors :

    1. In the _heapify function, the start variable is not an integer if l is not odd :

      var start = Math.floor( ( l - 2 ) / 2 );
      
    2. In the _siftDown function, you have used swap instead of swapr when you effectively swap the 2 elements of your array :

      swapr      = intl[root];  // <-- Here swapr instead of swap
      intl[root] = intl[swap];
      intl[swap] = swapr;       // <-- Here swapr instead of the 1st occurrence of swap
      root       = swapr;       // <-- Here swapr instead of swap