C 语言实现的优先级队列

C 语言实现的优先级队列

priorityqueue.h

/*******************************************************************************
* Copyright © 2024-2025 Light Zhang <mapaware@hotmail.com>, MapAware, Inc.     *
* ALL RIGHTS RESERVED.                                                         *
*                                                                              *
* PERMISSION IS HEREBY GRANTED, FREE OF CHARGE, TO ANY PERSON OR ORGANIZATION  *
* OBTAINING A COPY OF THE SOFTWARE COVERED BY THIS LICENSE TO USE, REPRODUCE,  *
* DISPLAY, DISTRIBUTE, EXECUTE, AND TRANSMIT THE SOFTWARE, AND TO PREPARE      *
* DERIVATIVE WORKS OF THE SOFTWARE, AND TO PERMIT THIRD - PARTIES TO WHOM THE  *
* SOFTWARE IS FURNISHED TO DO SO, ALL SUBJECT TO THE FOLLOWING :               *
*                                                                              *
* THE COPYRIGHT NOTICES IN THE SOFTWARE AND THIS ENTIRE STATEMENT, INCLUDING   *
* THE ABOVE LICENSE GRANT, THIS RESTRICTION AND THE FOLLOWING DISCLAIMER, MUST *
* BE INCLUDED IN ALL COPIES OF THE SOFTWARE, IN WHOLE OR IN PART, AND ALL      *
* DERIVATIVE WORKS OF THE SOFTWARE, UNLESS SUCH COPIES OR DERIVATIVE WORKS ARE *
* SOLELY IN THE FORM OF MACHINE - EXECUTABLE OBJECT CODE GENERATED BY A SOURCE *
* LANGUAGE PROCESSOR.                                                          *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON - INFRINGEMENT.IN NO EVENT   *
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE    *
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,  *
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  *
* DEALINGS IN THE SOFTWARE.                                                    *
*******************************************************************************/
/*
** @file priorityqueue.h
** @brief Priority Queue implementation in C
**
** @author mapaware@hotmail.com
** @copyright © 2024-2030 mapaware.top All Rights Reserved.
** @version 1.0.0
**
** @since 2024-11-21 21:54:30
** @date
**
** @note
**   see: http://btechsmartclass.com/data_structures/max-heap.html
* 
* Usage:

    // same as: PQueueNew(256, PQMaxHeapComp, PQElemSwap)
    PQueue_t* pq = PQueueNew(256, 0, 0);

    PQueuePush(pq, (PQElem_t)40);
    PQueuePush(pq, (PQElem_t)10);
    PQueuePush(pq, (PQElem_t)60);
    PQueuePush(pq, (PQElem_t)50);
    PQueuePush(pq, (PQElem_t)20);
    PQueuePush(pq, (PQElem_t)20);

    const PQElem_t* elt = PQueueTop(pq);
    printf(">>top=%lld\n", (int64_t)(*elt)); // >>top=60

    PQueuePop(pq, 0);  // drop the toppest element(=60) here
    elt = PQueueTop(pq);
    printf(">>top=%lld\n", (int64_t)(*elt)); // >>top=50

    int64_t n = 50;
    PQueuePop(pq, (const PQElem_t*)&n);    // drop the element(=50) here
    elt = PQueueTop(pq);
    printf(">>top=%lld\n", (int64_t)(*elt)); // >>top=40

    PQueueFree(pq, 0);
* 
*/
#ifndef PRIORITY_QUEUE_H_
#define PRIORITY_QUEUE_H_


#if defined(__cplusplus)
extern "C"
{
#endif

#include <stdio.h>
#include <stdint.h>


typedef void* PQElem_t;


typedef struct
{
    int (*compfunc)(const PQElem_t *, const PQElem_t *);
    void (*swapfunc)(PQElem_t*, PQElem_t*);

    size_t capcity;
    size_t length;
    PQElem_t elems[0];
} PQueue_t;

static void _PQBuildHeap(PQueue_t* pq, ssize_t size, ssize_t i)
{
    if (size > 1) {
        // Find the largest among root, left child and right child
        ssize_t largest = i;
        ssize_t l = 2 * i + 1;
        ssize_t r = 2 * i + 2;

        if (l < size && pq->compfunc(&pq->elems[l], &pq->elems[largest]) > 0) {
            largest = l;
        }
        if (r < size && pq->compfunc(&pq->elems[r], &pq->elems[largest]) > 0) {
            largest = r;
        }

        // Swap and continue heapifying if root is not largest
        if (largest != i) {
            pq->swapfunc(&pq->elems[i], &pq->elems[largest]);
            _PQBuildHeap(pq, size, largest);
        }
    }
}


static int PQMaxHeapComp(const PQElem_t* elt1, const PQElem_t* elt2)
{
    PQElem_t v1 = (PQElem_t)(*elt1);
    PQElem_t v2 = (PQElem_t)(*elt2);
    return (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
}

static int PQMinHeapComp(const PQElem_t* elt1, const PQElem_t* elt2)
{
    PQElem_t v1 = (PQElem_t)(*elt1);
    PQElem_t v2 = (PQElem_t)(*elt2);
    return (v1 > v2 ? -1 : (v1 < v2 ? 1 : 0));
}


static void PQElemSwap(PQElem_t * elt1, PQElem_t * elt2)
{
    PQElem_t elt = *elt1;
    *elt1 = *elt2;
    *elt2 = elt;
}


static PQueue_t * PQueueNew(size_t capcity, int (*comp)(const PQElem_t*, const PQElem_t*), void (*swap)(PQElem_t*, PQElem_t*))
{
    PQueue_t * pq = (PQueue_t *) malloc(sizeof(PQueue_t) + sizeof(PQElem_t) * capcity);
    if (pq) {
        pq->capcity = capcity;
        pq->length = 0;
        pq->compfunc = comp? comp: PQMaxHeapComp;
        pq->swapfunc = swap? swap: PQElemSwap;
    }
    return pq;
}


static const PQElem_t * PQueueTop(const PQueue_t* pq)
{
    if (pq->length) {
        return &pq->elems[0];
    }
    return 0;
}


// Function to insert an element into the tree
static int PQueuePush(PQueue_t* pq, const PQElem_t elt) {
    if (! pq->length) {
        pq->elems[0] = elt;
        pq->length++;
        // success
        return 1;
    }
    else if (pq->length != pq->capcity) {
        pq->elems[pq->length++] = elt;
        for (ssize_t i = pq->length / 2 - 1; i >= 0; i--) {
            _PQBuildHeap(pq, pq->length, i);
        }
        // success
        return 1;
    }
    else {
        // overflow
        return 0;
    }
}


// Function to delete an element from the tree
static PQElem_t * PQueuePop(PQueue_t* pq, const PQElem_t* eltp)
{
    ssize_t i = 0;
    if (eltp) {
        for (; i != pq->length; i++) {
            if (!pq->compfunc(&pq->elems[i], eltp)) {
                break;
            }
        }
    }
    if (i != pq->length) {
        pq->swapfunc(&pq->elems[i], &pq->elems[pq->length - 1]);
        pq->length--;

        for (i = (ssize_t) pq->length / 2 - 1; i >= 0; i--) {
            _PQBuildHeap(pq, pq->length, i);
        }

        return &pq->elems[pq->length];
    }

    // no element pop
    return 0;
}


static void PQueueFree(PQueue_t* pq, void (*elemdtor)(PQElem_t*))
{
    if (pq) {
        if (elemdtor) {
            ssize_t i = 0;
            PQElem_t* elt = pq->elems;
            while (i++ != pq->length) {
                elemdtor(elt++);
            }
        }
        free(pq);
    }
}

#ifdef __cplusplus
}
#endif
#endif /* PRIORITY_QUEUE_H_ */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/922377.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解 目录 GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GWO-SVMD灰狼算法优化逐次变分模态分解 内有15种用以优化svmd的适应度函数&#…

初识Linux—— 基本指令(下)

前言&#xff1a; 本篇继续来学习Linux的基础指令&#xff0c;继续加油&#xff01;&#xff01;&#xff01; 本篇文章对于图片即内容详解&#xff0c;已同步到本人gitee&#xff1a;Linux学习: Linux学习与知识讲解 Linux指令 1、查看文件内容的指令 cat ​ cat 查看文件…

在SQLyog中导入和导出数据库

导入 假如我要导入一个xxx.sql&#xff0c;我就先创建一个叫做xxx的数据库。 然后右键点击导入、执行SQL脚本 选择要导入的数据库文件的位置&#xff0c;点击执行即可 注意&#xff1a; 导入之后记得刷新一下导出 选择你要导出的数据库 右键选择&#xff1a;备份/导出、…

如何进行高级红队测试:OpenAI的实践与方法

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI模型的安全性和可靠性已经成为业界关注的核心问题之一。为了确保AI系统在实际应用中的安全性&#xff0c;红队测试作为一种有效的安全评估方法&#xff0c;得到了广泛应用。近日&#xff0c;OpenAI发布了两…

ES 基本使用与二次封装

概述 基本了解 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它提供了对海量数据的快速全文搜索、结构化搜索和分析功能&#xff0c;是目前流行的大数据处理工具之一。主要特点即高效搜索、分布式存储、拓展性强 核心功能 全文搜索:…

Java项目实战II基于SPringBoot的玩具销售商城管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着儿童娱乐与教育需求的…

Python安装出现严重错误的解决方法_0x80070643-安装时发生严重错误

使用这个软件MicrosoftProgram_Install_and_Uninstall.meta.diagcab把关于Python一个个组件全部删除&#xff0c;然后就能够重新安装Python了 修复阻止程序安装或删除的问题 - Microsoft 支持 这里下载

Java语言编程,通过阿里云mongo数据库监控实现数据库的连接池优化

一、背景 线上程序连接mongos超时&#xff0c;mongo监控显示连接数已使用100%。 java程序报错信息&#xff1a; org.mongodb.driver.connection: Closed connection [connectionId{localValue:1480}] to 192.168.10.16:3717 because there was a socket exception raised by…

微信小程序全局配置:导航栏、下拉刷新与上拉触底设置教程

微信小程序全局配置:导航栏、下拉刷新与上拉触底设置教程 引言 微信小程序作为一种新兴的轻量级应用,凭借其便捷性和丰富的功能受到了广泛的欢迎。在开发小程序的过程中,合理配置全局属性是提升用户体验的关键。本文将深入探讨小程序的全局配置中的window选项,重点介绍导…

YOLOv11融合[ECCV 2018]RCAN中的RCAB模块及相关改进思路

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Image Super-Resolution Using Very Deep Residual Channel Attention Networks》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/1807…

linux ubuntu的脚本知

目录 一、变量的引用 二、判断指定的文件是否存在 三、判断目录是否存在 四、判断最近一次命令执行是否成功 五、一些比较符号 六、"文件"的读取和写入 七、echo打印输出 八、ubuntu切换到root用户 N、其它可以参考的网址 脚本功能强大&#xff0c;用起来也…

前端:JavaScript (学习笔记)【2】

目录 一&#xff0c;数组的使用 1&#xff0c;数组的创建 [ ] 2&#xff0c;数组的元素和长度 3&#xff0c;数组的遍历方式 4&#xff0c;数组的常用方法 二&#xff0c;JavaScript中的对象 1&#xff0c;常用对象 &#xff08;1&#xff09;String和java中的Stri…

【Git】工作区、暂存区和版本库

目录 一、基本概念&#xff1a; 关系图&#xff1a; 1. 工作区&#xff08;Working Directory&#xff09; $ 1.1 工作区功能 $ 1.2 工作区特点 2. 暂存区&#xff08;Staging Area&#xff09; $ 2.1 暂存区功能 $ 2.2 暂存区特点 $ 2.3 常用命令 3. 版本库&#xff08…

【Linux | 计网】TCP协议详解:从定义到连接管理机制

目录 1.TCP协议的定义&#xff1a; 2.TCP 协议段格式 3.TCP两种通信方式 4.确认应答(ACK)机制 解决“后发先至”问题 5.超时重传机制 那么, 超时的时间如何确定? 6.连接管理机制&#xff1a; 6.1.三次握手&#xff1a; 为什么需要3次握手&#xff0c;一次两次不行吗…

Springboot系列之:创建Springboot项目,Springboot整合MyBatis-plus

Springboot系列之&#xff1a;创建Springboot项目&#xff0c;Springboot整合MyBatis-plus 一、快速创建Spring boot项目二、项目完整目录三、pom.xml四、application.yaml五、实体类六、mapper七、IService接口八、Service实现类九、配置类十、枚举十一、增删改查测试类十二、…

java基础面试题笔记(基础篇)

网上始终找不到令自己满意的面试题&#xff0c;所以我打算自己整理面试题&#xff0c;从简单的到难的&#xff0c;尽量简单准确描述回答降低大家理解和背的难度&#xff0c;有错误或者有更好的回答请在评论回复我&#xff0c;感谢大家。 什么是java&#xff1f; 回答&#xff…

编译 LLVM 源码,使用 Clion 调试 clang

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 1. LLVM 简介 LLVM 是一个开源的编译器基础架构&#xff0c;最初由 Chris Lattner 于 2000 年在伊利诺伊大学开发&#xff0c;后来成为一个广泛应用于编译器和…

[代码随想录打卡Day22] 理论基础 77. 组合 216.组合总和III 17.电话号码的字母组合

理论基础 有递归就有回溯。回溯搜索是一种纯暴力搜索算法。我们一层一层递归到最底层收获结果&#xff0c;比如下面我们最后一层1操作之后&#xff0c;我们只有撤销这个操作回退到上一个节点才能遍历该层的其他节点&#xff0c;这个回退撤销操作就是回溯。 回溯法&#xff0…

大模型工程化部署:使用FastChat部署基于OpenAI API兼容大模型服务

FastChat是加州大学伯克利分校LM-SYS发布的一个用于训练、服务和评估基于大型语言模型的聊天机器人的开放平台。 项目地址&#xff1a;https://github.com/lm-sys/FastChat.git 其核心功能包括&#xff1a; 最先进 LLM 模型的权重、训练代码和评估代码。 带有 WebUI 和与 Op…

102.【C语言】数据结构之用堆对数组排序

0.前置知识 向上调整: 向下调整: 1.对一个无序的数组排升序和降序 排升序问题 建大根堆还是小根堆? 错误想法 由小根堆的定义:树中所有的父节点的值都小于或等于孩子节点的值,这样排出来的数组时升序的,建小根堆调用向上调整函数即可(把画圈的地方改成<即可) arr未…