MaxHeapify call yields numbers not in the original array

62 views Asked by At

I'm working on implementing a max-heap from pseudo code in my book and I'm getting strange results after calling the "buildMaxHeap" function. For example, an integer array intHeap with elements {20, 5, 10, 12, 15, 8, 2, 6, 2, 9} is resulting in elements {20, 1066192077, 15, 12, 9, 10, 2, 6, 2, 5}. I noticed the first 5 elements are almost sorted in descending order which is encouraging.

Here's my implementation thus far (with some irrelevant code removed):

#define HEAPSIZE 10
int main()
{   
    int intHeap[HEAPSIZE] = {20, 5, 10, 12, 15, 8, 2, 6, 2, 9};

    std::cout << "Displaying intHeap before buildMaxHeap" << std::endl; 
    displayHeap(intHeap);
    buildMaxHeap(intHeap);
    std::cout << "Displaying intHeap after buildMaxHeap" << std::endl;
    displayHeap(intHeap);

    return 0;
}

// maintains max-heap property for array (sifts down)
template <typename T> void maxHeapify(T* array, int i)
{
    // left, right, and largest are positions in the array
    int left = i*2, right = i*2+1, largest;

    if(left <= HEAPSIZE && array[left] > array[i])
        largest = left;
    else
        largest = i;

    if(right <= HEAPSIZE && array[right] > array[largest])
        largest = right;

    if(largest != i)
    {
        swap(&array[i], &array[largest]);
        maxHeapify(array, largest);
    }
}

// builds the max heap
template <typename T> void buildMaxHeap(T* array)
{
    for(unsigned int i = HEAPSIZE / 2; i >= 1; i--)
        maxHeapify(array, i);
}

I'm really having a lot of trouble figuring out how the 10 digit number is ending up in array[1] position since it doesn't even belong in the original array.

EDIT-> I think I got it working after that array indexing issue.

// maintains max-heap property for array (sifts down)
template <typename T> void maxHeapify(T* array, int i)
{
    // left, right, and largest are positions in the array
    int left = LEFT(i), right = RIGHT(i), largest;

    if(left <= (HEAPSIZE - 1) && array[left] > array[i])
        largest = left;
    else
        largest = i;

    if(right <= (HEAPSIZE - 1) && array[right] > array[largest])
        largest = right;

    if(largest != i)
    {
        swap(&array[i], &array[largest]);
        maxHeapify(array, largest);
    }
}

// builds the max heap
template <typename T> void buildMaxHeap(T* array)
{
    for(int i = (HEAPSIZE-1) / 2; i >= 0; --i)
        maxHeapify(array, i);
}

Which appears to agree with my book's example. I also had to change the variable i in buildMaxHeap from unsigned int to just normal int for some reason (it was showing values below 0 ... I thought unsigned only could be positive? Does anyone know why that might happen?).

Anyway, thanks for pointing out the array indexing issue!

2

There are 2 answers

0
PaulMcKenzie On

1) What does your debugger tell you?

2) In your function, what if left == HEAPSIZE or right == HEAPSIZE?

if(left <= HEAPSIZE && array[left] > array[i])
    largest = left;

if(right <= HEAPSIZE && array[right] > array[largest])

You then go on and access array[largest], which is out of bounds.

1
Dietmar Kühl On

In C++ arrays are zero based, i.e., an array of n elements uses indices 0, 1, ..., n-1. Your code assumes it is one based.