#include <stdio.h>
#define heap_step 128
typedef struct _heap_t
{
void** data;
int cap_size;
int size;
int (*compare)(void*, void*);
}heap_t;
static void heap_init(heap_t* heap, int (*compare)(void*, void*))
{
heap->cap_size = heap_step;
heap->data = (void*)malloc(sizeof(void*) * heap->cap_size);
heap->size = 0;
heap->compare = compare;
}
static void heap_static(heap_t* heap)
{
free(heap->data);
}
static void heap_add_check(heap_t* heap, int index)
{
int p = 0;
while(index > 0)
{
p = (index - 1) / 2;
if (heap->compare(heap->data[p], heap->data[index]) > 0) // 字节点小于就向上替换
{
void* tmp = heap->data[p];
heap->data[p] = heap->data[index];
heap->data[index] = tmp;
index = p;
}
else
{
break;// 如果是字节点大于
}
}
}
static void heap_add(heap_t* heap, void* data)
{
if (NULL == heap || NULL == data)
{
return;
}
if (heap->size >= heap->cap_size) // 扩大内存
{
heap->cap_size += heap_step;
heap->data = realloc(heap->data, heap->cap_size);
}
heap->data[heap->size++] = data;
heap_add_check(heap, heap->size - 1); // 把数据放在尾部,向上检查
}
static int heap_del_hole(heap_t* heap, int index)
{
if (NULL == heap)
{
return;
}
int left = 0, right = 0;
while (1)
{
left = index * 2 + 1;
right = index * 2 + 2;
if (left >= heap->size) // 没有左右节点
{
return index;
}
if (right >= heap->size) // 没有右节点
{
heap->data[index] = heap->data[left];
return left;
}
// 找到最小的叶子节点
if (heap->compare(heap->data[left], heap->data[right]) < 0)
{
heap->data[index] = heap->data[left];
index = left;
}
else
{
heap->data[index] = heap->data[right];
index = right;
}
}
}
static void heap_del(heap_t* heap, int index)
{
if (NULL == heap)
{
return;
}
if (index > heap->size)
{
return;
}
if (index == heap->size - 1)
{
heap->size--;
return;
}
// min leaf
int hole = heap_del_hole(heap, index);
// 将这个最后的一个元素,赋值给这个找到的最小节点
heap->data[hole] = heap->data[--heap->size];
// 然后将这个最小节点看作是新插入的节点,进行向上替换
heap_add_check(heap, hole);
}