1. 程式人生 > >C語言最小堆

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