-1

Here's how I created my binary heap:

int *heapArray; // pointer to array of elements in heap
int capacity = 0; // maximum possible size of min heap
int heap_size; // Current number of elements in min heap
int d = 2;

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

void swap(double *x, double *y)
{
    double temp = *x;
    *x = *y;
    *y = temp;
}

double returnHeapValue(int key)
{
    return heapArray[key];
}

void initialize(int cap)
{
    heap_size = 0;
    capacity = cap;
    heapArray = (double*)malloc(cap*sizeof(double));
}

void insertJob(double x)
{
    if(capacity < 10)
    {
        capacity = 10;
        heapArray = (double*)realloc(heapArray,capacity*sizeof(double));
    }
    if(heap_size == capacity/2)
    {
        capacity += 10;
        heapArray = (double*)realloc(heapArray,capacity*sizeof(double));
    }

    heap_size = heap_size + 1;
    heapArray[heap_size] = x;
    maxHeapSwim(heap_size);
}

void maxHeapSwim(int k)
{
    while(k > 1 && heapArray[parent(k)] < heapArray[k] && k!=1)
    {
        swap(&heapArray[k],&heapArray[parent(k)]);
        k = parent(k);
    }
}

This is what I did in the main method to insert a bunch of doubles and then print them out:

int main()
{

  // test
  initialize(20);

  insertJob(2.0);
  insertJob(3.0);
  insertJob(1.0);
  insertJob(6.0);
  insertJob(4.0);
  insertJob(14.0);
  insertJob(7.0);
  insertJob(9.0);
  insertJob(8.0);
  insertJob(11.0);

  printf("\n");
  printf("%f", returnHeapValue(1));
  printf("\n");
  printf("%f", returnHeapValue(2));
  printf("\n");
  printf("%f", returnHeapValue(3));
  printf("\n");
  printf("%f", returnHeapValue(4));
  printf("\n");
  printf("%f", returnHeapValue(5));
  printf("\n");
  printf("%f", returnHeapValue(6));
  printf("\n");
  printf("%f", returnHeapValue(7));
  printf("\n");
  printf("%f", returnHeapValue(8));
  printf("\n");
  printf("%f", returnHeapValue(9));
  printf("\n");
  printf("%f", returnHeapValue(10));
  printf("\n");

  return 0;
}

However, this is what the output looks like:

0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000

Why aren't the numbers being printer properly? Is there something I'm doing wrong? When I test it out with Integer values, then everything works fine. But it's not working when I try to insert values of the "double" data type.

EDIT:

I also tried changing the type of heapArray from int to double like this:

double *heapArray;

Unfortunately, that lead to an error in another function that I created:

double delMaxPriorityJob() //This function deletes the largest value (in the root)
{
    double max = heapArray[1];
    swap(&heapArray[1],&heapArray[heap_size]);
    heap_size = heap_size - 1;
    maxHeapSink(1);
    heapArray[heap_size + 1] = NULL; //The error is in this line
    return max;
}

The error says:

"Incompatible types when assigning to type 'double' from type 'void *'"

Bob K
  • 69
  • 1
  • 9
  • `int *heapArray;` probably you want `double* heapArray;`? – Iłya Bursov Jan 06 '19 at 16:20
  • @IłyaBursov Check my edit – Bob K Jan 06 '19 at 16:26
  • 1
    `NULL` is not a `double`. Why do you find that error surprising? – rici Jan 06 '19 at 16:49
  • NONE of the posted code compiles. Amongst other problems, they are missing the needed `#include` statements for the needed header files. Please post a [mcve] – user3629249 Jan 06 '19 at 16:51
  • OT: regarding: `heapArray = (double*)malloc(cap*sizeof(double));` when calling any of the heap allocation functions: `malloc` `calloc` `realloc`, always check (!=NULL) the returned value to assure the operation was successful. 2) the returned type is `void*` which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. – user3629249 Jan 06 '19 at 16:56
  • OT: regarding this kind of statement: `heapArray = (double*)realloc(heapArray,capacity*sizeof(double));` should not assign the returned value from `realloc()` directly to the target variable. Because when `realloc()` fails, the pointer to the allocated heap memory will be lost. The result is an unrecoverable memory leak. Suggest assigning to a temp variable, check the temp variable and if the call to `realloc()` was successful, then copy the value from temp to the target variable – user3629249 Jan 06 '19 at 17:00
  • the posted code is missing a prototype for the function: `maxHeapSwim()` I.E. the function is being called before the compiler knows anything about the function – user3629249 Jan 06 '19 at 17:07
  • the posted code is missing the function: `parent()` – user3629249 Jan 06 '19 at 17:09
  • what are you expecting `maxHeapSwim()` to do? It seems that code is useless in the current context – user3629249 Jan 06 '19 at 17:13
  • 1
    You treat you array as if it had a one-based index, but C arrays are zero-based. For example you should increase `heap_size` last thing in the insert function, otherwise you write one beyond the active array and never set `heapArray[0]`. Given that, it is likely that your `parent(k)` function is wrong, too. For zero-based indices, it should return `(k - 1) / 2` – M Oehm Jan 06 '19 at 17:14
  • regarding: `while(k > 1 && heapArray[parent(k)] < heapArray[k] && k!=1)` the first check confirms that 'k' is greater than 1, so the last check will never fail. Suggest removing the last check 'k!=1' – user3629249 Jan 06 '19 at 17:17
  • regarding: `if(heap_size == capacity/2)` what if the 'heap_size' is greater than 'capacity/2'? Suggest: `if(heap_size > capacity/2)` – user3629249 Jan 06 '19 at 17:19
  • the posted code is missing the function: `swap()` – user3629249 Jan 06 '19 at 17:22
  • the posted code is missing the function: `resetHeap()` – user3629249 Jan 06 '19 at 17:23
  • the posted code is missing the function: `count_heap_elements()` – user3629249 Jan 06 '19 at 17:24
  • the posted code is missing the function: `returnHeapValue()` – user3629249 Jan 06 '19 at 17:26
  • when compiling, always enable the warnings, then fix those warnings. ( for `gcc`, at a minimum use: `-Wall -Wextra -Wconversion -pedantic -std=gnu11` ) Note other compilers use different options to perform the same results – user3629249 Jan 06 '19 at 17:30
  • @rici NULL is not an integer either. But when I set heapArray to "int", then I didn't have that error. – Bob K Jan 07 '19 at 07:20
  • I want to set that unused node of the heap as NULL to prevent loitering. – Bob K Jan 07 '19 at 07:37
  • @M Oehm Arrays in Java are also zero-indexed. However, it's still possible to create a binary heap in java by treating an array like it's one-indexed. Check this link: https://algs4.cs.princeton.edu/24pq/ – Bob K Jan 07 '19 at 07:41
  • @user3629249 I added the missing functions to the question – Bob K Jan 07 '19 at 08:32

1 Answers1

0

I fixed it. The thing is, I'm trying to run the main() function from a different class. The reason it didn't work before is that I didn't specify the functions correctly in the binary heap's header file. This is what the header file looks like now:

extern void initialize(int cap);
extern void resetHeap();
extern int count_heap_elements();
extern int returnHeapCapacity();
extern double returnHeapValue(int key);
extern void insertJob(double x);
extern void insertEvent(double x);
extern double delMaxPriorityJob();
extern double delMaxPriorityEvent();
extern void maxHeapSink(int k);
extern void maxHeapSwim(int k);
extern void minHeapSwim(int k);
extern void minHeapSink(int k);

Now when I run that main() function from a different class, I get the correct outputs.

Bob K
  • 69
  • 1
  • 9