参考库函数sort逻辑写的优先级队列,测试基本类型和结构体可以实现功能
代码
c
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
typedef struct Heaps {
void *heap;
size_t elemSize;
int len;
int (*cmp)(const void *, const void *);
}Heap;
static int ParentIndex(int idex)
{
return ((idex + 1) >> 1) - 1;
// return (idex+1)/2-1;
}
static int LeftChildIndex(int idex)
{
return ((idex + 1) << 1) - 1;
// return (idex+1)*2-1;
}
static int RightChildIndex(int idex)
{
return LeftChildIndex(idex) + 1;
}
static void Swap(void *a, void *b, size_t elemSize)
{
//int tmp = *(int *)a;
//*(int *)a = *(int *)b;
//*(int *)b = tmp;
void *p = malloc(elemSize);
memcpy(p, a, elemSize);
memcpy(a, b, elemSize);
memcpy(b, p, elemSize);
free(p);
return;
}
void *FindPointer(Heap *h, int index) {
return (void *)((const uint8_t *)(h->heap)+((index)*(h->elemSize)));
}
static void Sink(Heap *h)
{
int pos = 0;
while (pos < h->len) {
int leftPos = LeftChildIndex(pos);
int rightPos = RightChildIndex(pos);
if (leftPos >= h->len) break;
int maxPos = pos;
if((h->cmp)(FindPointer(h, leftPos), FindPointer(h, pos)) < 0) {
maxPos = leftPos;
}
if(rightPos < h->len && ((h->cmp)(FindPointer(h, rightPos), FindPointer(h, maxPos)) < 0)) {
maxPos = rightPos;
}
if(maxPos != pos) {
Swap(FindPointer(h, maxPos), FindPointer(h, pos), h->elemSize);
pos = maxPos;
}
else {
break;
}
}
}
static void FloatingUp(Heap *h)
{
int pos = h->len-1;
while(pos > 0) {
int parentPos = ParentIndex(pos);
void *p = FindPointer(h, parentPos);
void *q = FindPointer(h, pos);
if(((h->cmp)(p, q)) > 0) {
Swap(p, q, h->elemSize);
pos = parentPos;
}
else {
break;
}
}
return;
}
Heap *InitHeap(int k, size_t elemSize, int (*cmp)(const void *, const void *)) {
Heap *h = (Heap *)malloc(sizeof(Heap));
h->heap = malloc(elemSize*k);
h->len = 0;
h->cmp = cmp;
h->elemSize = elemSize;
return h;
}
void HeapPush(Heap *h, void *v) {
//((int *)h->heap)[h->len++] = v;
void *p = FindPointer(h, h->len);
memcpy(p, v, h->elemSize);
h->len++;
FloatingUp(h);
}
void *HeapPop(Heap *h) {
void *res = malloc(h->elemSize);
memcpy(res, h->heap, h->elemSize);
void *p = FindPointer(h, h->len-1);
memcpy(h->heap, p, h->elemSize);
//((int *)h->heap)[0] = ((int *)h->heap)[h->len-1];
h->len--;
Sink(h);
return res;
}
void HeapDestroy(Heap *h)
{
free(h->heap);
free(h);
}
使用
c
typedef struct {
int a;
int b;
} Elemtype;
// 小顶堆
int cmp(const void *a, const void *b) {
return ((Elemtype *)a)->a - ((Elemtype *)b)->a;
}
Elemtype tmp[] = {
{.a = 3, .b = 5},
{.a = 6, .b = 7},
{.a = 1, .b = 8},
};
int n = sizeof(tmp)/sizeof(Elemtype);
// 初始化堆大小,堆元素大小, 比较函数
Heap *h = InitHeap(n, sizeof(Elemtype), cmp);
for(int i=0; i<n; i++) {
HeapPush(h, (void *)&(tmp[i]));
}
while(h->len > 0) {
Elemtype *p = (Elemtype *)HeapPop(h);
printf("%d %d\n", p->a, p->b);
}
HeapDestroy(h);