C語言最小堆
阿新 • • 發佈:2019-01-01
#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); }
#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); }