0

The for's I have trouble with are the one in buildHeap and buildMinHeap. Previously, those didn't trigger at all which is why I know the printing part should more or less work as it printed the nodes properly, if with the unsorted array.

Currently I assume I have an infinite loop in there as the program crashes after displaying some of the debug messages I put in. I ran out of ideas on what could be wrong. Any ideas?

#include <stdio.h>

#define ARRAY_SIZE 10

int parent(int i) {
    return i/2;
}

int left(int i) {
    return 2*i;
}

int right(int i) {
    return 2*i+1;
}

void heapify(int A[], int i, int s) {
    int m = i;
    int temp;
    int l = left(i);
    int r = right(i);

    if (l <= s && A[l] > A[m]) m = l;
    if (r <= s && A[r] > A[m]) m = r;
    if (i != m) {
        temp = A[i];
        A[i] = A[m];
        A[m] = temp;
        heapify(A, m, s);
    }
    printf("heapify done\n");

}

void buildHeap(int A[]) {
    int i;

    for (i = ARRAY_SIZE / 2; i > 0; i--) {
        heapify(A, i, ARRAY_SIZE);
    }
    printf("buildHeap done\n");
}

// this still creates a normal heap, not a min heap afaik
void buildMinHeap(int A[]) {
    int s = ARRAY_SIZE - 1;
    int i;
    int temp;

    buildHeap(A);

    for (i = ARRAY_SIZE; i > 1; i--) {
        temp = A[i];
        A[i] = A[1];
        A[1] = temp;
        s = s-1;
        heapify(A, 1, s);
    }
}

void printHeap(int A[]) {
    int i;

    printf("graph g {\n");

    for (i = 0; i < ARRAY_SIZE; i++) {
        printf("%d -- %d\n", parent(i), A[i]);
    }

    printf(" }\n");

    //temp debug code
    printf("[ ");
    i = 0;
    for (i = 0; i < ARRAY_SIZE; i++) {
    printf("%d", A[i]);
    if (i < ARRAY_SIZE - 1) printf(", ");
    }
    printf(" ]\n");
}

int main() {
    int array[ARRAY_SIZE] = {4, 3, 2, 5, 6, 7, 8, 9, 12, 1};

    buildMinHeap(array);
    printHeap(array);
}

EDIT: Oh, also, I'm still a student so not that versed in C just yet. Just to give some context.

enenra
  • 111
  • 1
  • 11
  • Your problem here is definitely the `heapify` function. I'm not absolutely sure what it should do. Can you explain this? Also, if you look at your `left` function, I'm surprised that it would always return `2`... – Matt Ko Mar 30 '15 at 16:03
  • Thanks for looking into it. The heapify function is based on an algorithm that we got provided with in class: `Algo: Heapify(A,i,s) m = i; l = Left(i); r = Right(i); if l ≤s ∧ A[l] >A[m] then m = l; if r ≤s ∧ A[r] >A[m] then m = r; if i 6=m then exchange A[i] and A[m]; Heapify(A,m,s);` Did I maybe implement it wrongly? Also, the `left` part: That is a typo, yeah, that 1 should be an i. EDIT: ohgod the formatting... – enenra Mar 30 '15 at 16:49
  • By fixing the `left`function, the code now gives me an output but it is definitely not the right one. – enenra Mar 30 '15 at 16:57
  • 1
    Note that the formulas you are using are correct for arrays indexed from 1..N. C uses indexes from 0..N-1. This may account for some of your problems, unless you've consciously created arrays with `type array[N+1];` and only used indexes 1..N after all. I've not chased through your code to see whether this is really the cause of your trouble, but it could be. – Jonathan Leffler Mar 30 '15 at 17:52
  • Thanks. I have adjusted the two for loops in buildMinHeap and buildHeap to reflect that and I think it should be correct now. The output is also much saner now but still not correct from what I can tell, since I get `graph g { 0 -- 1 1 -- 3 1 -- 2 2 -- 5 2 -- 6 3 -- 7 3 -- 8 4 -- 9 4 -- 12 }` and the nodes 4,9 and 12 are separate from the "main" tree in their own one (4 doesn't seem to have a parent node) – enenra Mar 30 '15 at 18:07

1 Answers1

0

In C, arrays use zero-based indexing. I.e. an array with ten elements will have element indeces 0 to 9.

It looks like you have assumed that array element will be indexed from 1 to ARRAY_SIZE, when in fact they are indexed 0 to ARRAY_SIZE - 1.

Try a very simple main function, that just outputs the contents of the array, before you try doing anything with it:

#include <stdio.h>

#define ARRAY_SIZE    10

int main(void)
{
    int index;
    int array[ARRAY_SIZE] = {4, 3, 2, 5, 6, 7, 8, 9, 12, 1};

    for(index = ARRAY_SIZE - 1; index >= 0; index--)
    {
        printf("myArray[%d] == %d\n",index,myArray[index]);
    }
    return 0;
}

You could even add some helper constants:

#define ARRAY_FIRST    0
#define ARRAY_LAST     (ARRAY_SIZE -1)
Evil Dog Pie
  • 2,300
  • 2
  • 23
  • 46
  • Thanks for the tips! I think I have adjusted the loops to take 0 to n-1 into consideration now. The output I get seems ok except that it seems to be based on a 0-node: `graph g { 0 -- 4 0 -- 1 1 -- 3 1 -- 2 2 -- 5 2 -- 6 3 -- 7 3 -- 8 4 -- 9 4 -- 12 } [ 4, 1, 3, 2, 5, 6, 7, 8, 9, 12 ]` instead of 1, since 0 isn't actually in the array. – enenra Mar 30 '15 at 18:18
  • @enenra I suggest that you call your `printHeap` function at the end of `heapify`, so that you can see what's going on at each stage. Maybe print the paramters that are being passed to the function on entry as well. Give yourself as much information you can - that's debugging. – Evil Dog Pie Mar 31 '15 at 08:02