【C语言】队列(Queue)C语言实现,栈基本操作,编译通过,已测试,可直接使用

QueueStruct.h

/**********************************************************************************
 * @file QueueStruct.h
 * @brief 队列结构及其常用操作(C语言实现)
 * 
 * @attention
 * 
 * @note    可选队列实现方式,链表或数组
 * 使用数组实现队列的优点和缺点:
 *  优点:
 *      实现简单:使用数组实现队列比较直观和简单,不需要考虑指针之间的连接关系。
 *      内存占用少:数组在内存中是一块连续的存储空间,相比链表在存储指针的开销上要少一些。
 *  缺点:
 *      静态大小:数组的大小在初始化时就确定,队列的大小受限于数组大小,无法动态扩展。
 *      频繁的操作影响性能:在队列头部插入或删除元素时,需要频繁地搬移数组元素,影响性能。
 * 
 * 使用链表实现队列的优点和缺点:
 *  优点:
 *      动态大小:链表实现的队列可以动态扩展或缩小,不受固定大小的限制,更加灵活。
 *      插入、删除性能好:在链表的头尾进行插入、删除操作时,时间复杂度为 O(1)。
 *  缺点:
 *      占用更多内存:链表中每个节点都需要存储指针信息,会占用更多的内存空间。
 *      实现复杂:相比数组实现,链表需要考虑指针的操作和连接,实现起来相对复杂一些。
 *总结:个人认为,由于现在MCU内存容量的提升,链表的实现方式,除了实现复杂,其余都是优点。
 *
 * 
 * @version V1.0
 *              - 编写队列数据结构(采用数组循环)和基本操作(创建、判空、判满、入队、出队)
 * 
 * @date 2024-03-22
**********************************************************************************/
#ifndef __QUEUE_STRUCT__H_
#define __QUEUE_STRUCT__H_

#define QueueStruct_MAX_SIZE  100       // 队列内存大小


#pragma pack(1)

typedef enum
{
    __Queue_SUCCESSFUL  =  0,       // 操作成功,非满,非空
    __Queue_FAILEDL     =  -1,      // 操作失败
    __Queue_Is_EMPTY    =  1001,    // 队列空
    __Queue_Is_FULL     =  1002,    // 队列满

    __Queue_ERR_CODE_END
}E_QueueErrCode;

typedef struct
{
    void* aElement[QueueStruct_MAX_SIZE];

    int nFrontIndex;        // 队列头部索引
    int nRearIndex;         // 队列尾部索引
}T_Queue;

#pragma pack()

/**********************************************************************************
 * @brief 创建空队列
 * 
 * @param 
 * 
 * @return - T_Queue*
 * 
 * @details 
 * 
 * @note
**********************************************************************************/
T_Queue* CreateQueue();

/**********************************************************************************
 * @brief 判断队列是否空
 * 
 * @param   - T_Queue*
 * 
 * @return  - __SUCCESSFUL  非空
 *          - __FAILED      空
 *          - __ABNORMAL    其它异常
 * 
 * @details 
 * 
 * @note
**********************************************************************************/
int QueueIsEmpty(T_Queue* ptQueue);

/**********************************************************************************
 * @brief 判断队列是否满
 * 
 * @param   - T_Queue*
 * 
 * @return  - __SUCCESSFUL  非满
 *          - __FAILED      满
 *          - __ABNORMAL    其它异常
 * 
 * @details 
 * 
 * @note
**********************************************************************************/
int QueueIsFull(T_Queue* ptQueue);

/**********************************************************************************
 * @brief 队尾入队
 * 
 * @param   - T_Queue*
 * 
 * @return  - __FAILED
 *          - __SUCCESSFUL
 * 
 * @details 
 * 
 * @note
**********************************************************************************/
int EnterRearQueue(T_Queue* ptQueue, void* pElement);

/**********************************************************************************
 * @brief 队头出队
 * 
 * @param   - T_Queue*
 *          - void*     出队元素指针
 * 
 * @return  - __FAILED
 *          - __SUCCESSFUL
 * @details 
 * 
 * @note
**********************************************************************************/
int DeleteFrontQueue(T_Queue* ptQueue, void** pElement);

#endif  // __QUEUE_STRUCT__H_

QueueStruct.c

#include <stdio.h>
#include <stdlib.h>

#include "QueueStruct.h"


T_Queue* CreateQueue()
{
    T_Queue* tQueue = (T_Queue*)malloc(sizeof(T_Queue));
    if (NULL == tQueue) 
    {
        printf("<queue><create> Memory allocation failed.\n");
        return NULL;
    }

    tQueue->nFrontIndex = -1;
    tQueue->nRearIndex = -1;
    return tQueue;
}

int QueueIsEmpty(T_Queue* ptQueue)
{
    if ( (ptQueue->nFrontIndex == ptQueue->nRearIndex) || (-1 == ptQueue->nFrontIndex) && (-1 == ptQueue->nRearIndex) )
    {
        printf("<Queue><isEmpty><Error> Queue is empty.frot=%d, rear=%d\n", ptQueue->nFrontIndex, ptQueue->nRearIndex);
        return __Queue_Is_EMPTY;        // 队列空
    }
    else if ((ptQueue->nFrontIndex != ptQueue->nRearIndex) || (0 <= ptQueue->nRearIndex))
        return __Queue_SUCCESSFUL;
    else
    {
        printf("<Queue><isEmpty><Error> Queue is abnormal.frot=%d, rear=%d\n", ptQueue->nFrontIndex, ptQueue->nRearIndex);
        return __Queue_FAILEDL;
    }
}

int QueueIsFull(T_Queue* ptQueue)
{
    if ((QueueStruct_MAX_SIZE-1) <= ptQueue->nRearIndex)
    {
        printf("<Queue><isFull><Error> Queue is full.frot=%d, rear=%d\n", ptQueue->nFrontIndex, ptQueue->nRearIndex);
        return __Queue_Is_FULL;        // 队列满
    }
    else if ((QueueStruct_MAX_SIZE-1) >= ptQueue->nRearIndex)
        return __Queue_SUCCESSFUL;
    else
    {
        printf("<Queue><isFull><Error> Queue is abnormal.frot=%d, rear=%d\n", ptQueue->nFrontIndex, ptQueue->nRearIndex);
        return __Queue_FAILEDL;
    }
}

int EnterRearQueue(T_Queue* ptQueue, void* pElement)
{
    // 判满
    int nResult1 = QueueIsFull(ptQueue);
    if (__Queue_SUCCESSFUL != nResult1)
    {
        printf("<Queue><EnQue><Error> Queue is full or abnormal. QueueIsFull()=%d\n", nResult1);
        return __Queue_FAILEDL;
    }

    // ++ptQueue->nRearIndex;  // rear后移,没考虑取模,会有假性溢出问题
    ptQueue->nRearIndex = (ptQueue->nRearIndex+1) % QueueStruct_MAX_SIZE;   // 考虑取模,循环队列
    ptQueue->aElement[ptQueue->nRearIndex] = pElement;
    return __Queue_SUCCESSFUL;
}

int DeleteFrontQueue(T_Queue* ptQueue, void** pElement)
{
    // 判空
    int nResult = QueueIsEmpty(ptQueue);
    if (__Queue_SUCCESSFUL != nResult)
    {
        printf("<Queue><DeQue><Error> Queue is empty. QueueIsEmpty()=%d\n", nResult);
        return __Queue_FAILEDL;
    }

    // ++ptQueue->nFrontIndex; // front后移,没考虑取模,会有假性溢出问题
    ptQueue->nFrontIndex = (ptQueue->nFrontIndex+1) % QueueStruct_MAX_SIZE;     // 考虑取模
    *pElement = ptQueue->aElement[ptQueue->nFrontIndex];
    ptQueue->aElement[ptQueue->nFrontIndex] = NULL;
    
    return __Queue_SUCCESSFUL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

油炸自行车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值