优先级队列-C语言

参考库函数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);
相关推荐
abcy0712138 小时前
flink state实例
大数据·算法·flink
qizayaoshuap8 小时前
# [特殊字符] 密码生成器 — 鸿蒙ArkTS安全算法与密码强度评估系统
java·算法·安全·华为·harmonyos
良木林8 小时前
滑动窗口 - LeetCode hot 100
javascript·算法·leetcode·双指针·滑动窗口
华玥作者8 小时前
uniapp 万条数据不卡顿:我写了个虚拟列表组件 hy-list,原生支持瀑布流
数据结构·uni-app·list·vue3
2401_841495648 小时前
【数据结构】B*树
数据结构·c++·b树·算法·删除·插入·三分分裂
不如语冰9 小时前
AI大模型入门-模块导入import
数据结构·人工智能·pytorch·python
岑梓铭9 小时前
《考研408数据结构》第七章(7.1 查找:顺序查找、折半查找、分块查找)复习笔记
数据结构·笔记·考研·408·ds·查找
壹号用户9 小时前
c++入门之list了解及使用
数据结构·list
QXWZ_IA9 小时前
**电力登高作业高空失保实时监管:千寻智能安全带高挂低用监测方案**
人工智能·科技·算法·能源·智能硬件
来一碗刘肉面9 小时前
什么是双端队列
数据结构·链表