Search code examples
cpointersstructureheapsortmin-heap

how to use pointers to array for Min Heapsort in C?


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);
    }   
}

Solution

  • 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])