#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct s_minpq
{
int *data;
int capacity;
int size;
} t_minpq;
static inline int parent(int i)
{
return (i - 1) / 2;
}
static inline int left(int i)
{
return 2 * i + 1;
}
static inline int right(int i)
{
return 2 * i + 2;
}
t_minpq *create_minpq(int capacity)
{
t_minpq *pq = malloc(sizeof(*pq));
if (!pq)
return NULL;
pq->capacity = capacity;
pq->size = 0;
pq->data = malloc(sizeof(int) * capacity);
if (!pq->data)
{
free(pq);
return (NULL);
}
return pq;
}
void free_minpq(t_minpq *pq)
{
if (pq)
{
free(pq->data);
free(pq);
}
}
static void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void push_minpq(t_minpq *pq, int value)
{
if (pq->size == pq->capacity)
{
pq->capacity *= 2;
pq->data = realloc(pq->data, sizeof(int) * pq->capacity);
}
int i = pq->size++;
pq->data[i] = value;
while (i != 0 && pq->data[parent(i)] > pq->data[i])
{
swap(&pq->data[i], &pq->data[parent(i)]);
i = parent(i);
}
}
int pop_minpq(t_minpq *pq)
{
int i;
int small;
if (pq->size <= 0)
return (INT_MAX);
i = 0;
small = pq->data[0];
pq->data[0] = pq->data[--pq->size];
while (1)
{
int l = left(i);
int r = right(i);
int s = i;
if (l < pq->size && pq->data[l] < pq->data[s])
s = l;
if (r < pq->size && pq->data[r] < pq->data[s])
s = r;
if (s == i)
break;
swap(&pq->data[i], &pq->data[s]);
i = s;
}
return (small);
}
int main(void)
{
t_minpq *pq = create_minpq(4);
push_minpq(pq, 10);
push_minpq(pq, 5);
push_minpq(pq, 20);
push_minpq(pq, 1);
while (pq->size > 0)
{
printf("%d ", pop_minpq(pq));
}
free_minpq(pq);
return 0;
}
