0

I was trying to make heapsort using min heap, that too with a Structure that points to a array pointer. Now there is some logical error either in createHeap function or in heapify function. Note:Rest of the program need not to be check or edit, Heapify and createHeap need to modify according to the rest of the program.

   #include <stdio.h>
#include <stdlib.h>

// Max heap of length len and values stored in array
struct MinHeap{
    int size;
    int* array;
};

// Function declarations
void createHeap(struct MinHeap*);
void heapify(struct MinHeap* , int );
void heapSort(struct MinHeap*);
void swap(int*,int*);
void printArray(int*, int);

int main(){

    int numelems;
    scanf("%d",&numelems);
    int * arr = (int*) malloc(sizeof(int) * numelems);
    int i;

    for(i=0;i<numelems;i++)
    scanf("%d",&arr[i]);

    struct MinHeap* minHeap =  (struct MinHeap*) malloc(sizeof(struct MinHeap));
    minHeap->size                   = numelems;   // initialize size of heap
    minHeap->array                 = arr;     // Assign address of first element of array

    createHeap(minHeap);
    heapSort(minHeap);

    printArray(minHeap->array,numelems);
    return 0;
}

// heapSort function
void heapSort(struct MinHeap* minHeap){


    // Repeat following steps while heap size is greater than 1. 
    while (minHeap->size > 1){
        // The smallest item in Heap is stored at the root. Replace it with the last item of the heap followed by reducing the size of heap by 1.
        swap(&minHeap->array[0], &minHeap->array[minHeap->size - 1]);
        --minHeap->size;  // Reduce heap size

        // heapify the root of tree.
        heapify(minHeap, 0);
    }
} 

// function swap 2 integers
void swap(int* num1, int* num2){ 
    int temp = *num1;
    *num1    = *num2;  
    *num2    = temp; 
}

// prints an array of given size
void printArray(int* a, int len){
    int i;
    for (i = len-1; i >=0 ; i--)
        printf("%d ", a[i]);
}

void createHeap(struct MinHeap *heap)
{

    int len=heap->size-1,i;
    for(i=len;i>=0;i--)
    heapify(heap,i);
}
void heapify(struct MinHeap *heap,int i)
{
    int min;
    int right=2*i+2,left=i*2+1;
    if(right<heap->size-1 && heap->array+i>heap->array+right)
    min=right;
    else min =i;
    if(left<heap->size-1 && heap->array+i>heap->array+left)
    min=left;
    if(min!=i)
    {
        swap(heap->array+i,heap->array+min);
        heapify(heap,min);
    }   
}
0xC0d3
  • 77
  • 1
  • 10
  • For starters, `int main(void)` is the minimum signature that should be used for your `main` function – ryyker Mar 19 '18 at 12:32
  • @ryyker well I can not change the rest of the code except the heapify and createHeap function, it is the domain i can work on. – 0xC0d3 Mar 19 '18 at 12:38

2 Answers2

0

In heapify function you should compare values not pointers so change

heap->array+i>heap->array+right

to

heap->array[i]>heap->array[right]

Note: array[i] is just another way of writing *(array+i), so your code would work if changed it to *(heap->array + i) > *(heap->array + right) but in general, the brackets makes things much clearer.

In conditions which check if left, right indices are in range of array you should replace left < heap->size-1 by left <= heap->size-1 (to do the same thing with right index).

After these lines were executed

if(right<=heap->size-1 && heap->array[i]>heap->array[right])
    min=right;
else 
    min =i;

you should take min value to use in next comparison

if(left<=heap->size-1 && heap->array[min]>heap->array[left])
klutt
  • 30,332
  • 17
  • 55
  • 95
rafix07
  • 20,001
  • 3
  • 20
  • 33
  • ok it work at least for some cases. It is only giving right output for 1 test case out of 5 ( approzx this ratio) @rafix07 – 0xC0d3 Mar 19 '18 at 12:46
  • see my last update with checking indices in range of array – rafix07 Mar 19 '18 at 12:49
  • 10 10 9 8 7 6 5 4 3 2 1 //input _3 1 2 7 4 9 10 6 5 8_ //out put (incorrect) – 0xC0d3 Mar 19 '18 at 12:52
  • @H_Bhatt change `leftsize-1` to `left<=heap->size-1`, do the same with `right` index, and code will work. – rafix07 Mar 19 '18 at 12:56
  • these were the changes i made before the output i shared `for(i=len/2;i>=0;i--)` `if(right<=heap->size-1 && heap->array[i]>heap->array[right])` `if(left<=heap->size-1 && heap->array[i]>heap->array[min])` – 0xC0d3 Mar 19 '18 at 13:06
  • in last line you want to compare value pointed by `min` index with value pointed by `left` index, so change `if(left<=heap->size-1 && heap->array[min]>heap->array[left])`, look at the answer, it is there. – rafix07 Mar 19 '18 at 13:07
-1

// THIS WILL GUARANTEED WORK FOR YOU//

void createHeap(struct MinHeap *heap)
{
    int len=heap->size-1,i;
    for(i=len;i>=0;i--)
    heapify(heap,i);
}

void heapify(struct MinHeap *heap,int i)
{
    int min;
    int right=2*i+2,left=i*2+1;
    if(right<=heap->size-1 && *(heap->array + i) > *(heap->array + right))
    min=right;
    else min =i;

    if(left<=heap->size-1 && heap->array[min]>heap->array[left]
    {
         min=left;
    }

    if(min!=i)
    {
        swap(heap->array+i,heap->array+min);
        heapify(heap,min);
    }
}
FractalSpace
  • 5,577
  • 3
  • 42
  • 47