C语言最小堆

#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);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值