队列的基础实现

如下代码不是最终代码,本人没有对此代码编译过,如使用此代码,需自行解决一下编译问题,逻辑上面跟自己最终业务中使用的代码逻辑大体一致

头文件

#ifndef _QUEUE_H
#define _QUEUE_H

#define QUEQUE_MAX_NUN                (64)                                /* 队列最大个数 */

typedef struct stHttpClientInfo
{
    char szAppID[128];                  /* 南网:   应用ID */
    char szAppSecret[128];              /* 南网:   应用请求秘钥 */
    
    char szKey_uploadtype[16];          /* 表单key--uploadType */
    char szKey_fileFolder[16];          /* 表单key--fileFolder */
    char szKey_file[16];                /* 表单key--file */
    
    char szValue_uploadtype[256];       /* 表单Value--uploadType */
    char szValue_fileFolder[256];       /* 表单Value--fileFolder */
    char szValue_file[256];             /* 表单Value--file */
    
    char szfileName[64];                /* fileName信息 */
}stHttpClientInfo;

typedef struct QueueInfo
{
    int type;
    int lenth;
    stHttpClientInfo stClientInfo;
    void *pdata;
}QDataType;

typedef struct QueueNode
{
    QDataType data;         //储存数据
    struct QueueNode* next; //储存下一个结点地址
}QNode;
 
//记录队列头尾结点地址
typedef struct Queue
{
    QNode* head;  //储存头结点地址
    QNode* tail;  //储存尾结点地址
}Queue;
 
//初始化队列
int QueueInit(IN Queue *pq);
 
//销毁队列
int QueueDestory(IN Queue *pq);
 
//入列
int QueuePush(IN Queue *pq, IN QDataType *x);
 
//出列
int QueuePop(IN Queue *pq);

//判断队列是否为空
int QueueIsEmpty(IN Queue *pq);
 
//获取队列中元素个数
int QueueSize(IN Queue *pq, OUT size_t *size);
 
//获取队头元素
int QueueFront(IN Queue *pq, OUT QDataType *data);

//获取队尾元素
int QueueBack(IN Queue *pq, OUT QDataType *data);

#endif // _MSG_CTRL_H


源代码


#define Printf(format, ...) \
do\
{\
    printf("%s(%d):", __func__, __LINE__); \
    printf(format, ##__VA_ARGS__);         \
    printf("\n");         \
}\
while(0)


/**************************************************************************
    函数名称: QueueInit
    功能描述: 初始化队列 
    输入参数: IN Queue *pq            队列头
    输出参数: 无
    注 意 点: 
***************************************************************************/
int QueueInit(IN Queue *pq)
{
    if (NULL == pq)
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }

    pq->head = pq->tail = NULL;//置空
    
    return ERR_COMMON_SUCCEED;
}

/**************************************************************************
    函数名称: QueueDestory
    功能描述: 销毁队列 
    输入参数: IN Queue *pq            队列头
    输出参数: 无
    注 意 点: 
***************************************************************************/
int QueueDestory(IN Queue *pq)
{
    if (NULL == pq)
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }
    
    QNode* cur = pq->head;
    
    //从队头开始遍历销毁结点
    while (cur)
    {
        QNode* next = cur->next;//销毁前保存下一个结点地址
        
        if (NULL != cur->data.pdata)
        {
            free(cur->data.pdata);
            cur->data.pdata = NULL;
        }
        
        free(cur);
        cur = next;
    }
 
    pq->head = pq->tail = NULL;

    return 0;
}

/**************************************************************************
    函数名称: QueuePush
    功能描述: 数据入队列 
    输入参数: IN Queue *pq            队列头
              IN QDataType x      待入列的数据
    输出参数: 无
    注 意 点: 
***************************************************************************/
int QueuePush(IN Queue *pq, IN QDataType *x)
{
    int size = 0;
    
    if ((NULL == pq) || (NULL == x))
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }

    QueueSize(pq, (size_t *)&size);
    if (size > QUEQUE_MAX_NUN)
    {
        Printf("[MSG_CTRL]quesize is too big, size[%d]", size);
        QueuePop(pq);
    }
    
    //创建一个新的结点
    QNode *newnode =(QNode *)malloc(sizeof(QNode));
    if (NULL == newnode)
    {
        Printf("[MSG_CTRL]malloc failed, size[%lu]", sizeof(QNode));
        return ERR_COMMON_NO_MEMORY;
    }

    //将所要入列的元素赋值给新创建的结点
    newnode->data.pdata = (void *)malloc(x->lenth);
    if (NULL == newnode->data.pdata)
    {
        Printf("[MSG_CTRL]malloc fail, len[%d]", x->lenth);
        return ERR_COMMON_NO_MEMORY;
    }
    
    newnode->data.type = x->type;
    newnode->data.lenth = x->lenth;
    memcpy(&newnode->data.stClientInfo, &x->stClientInfo, sizeof(newnode->data.stClientInfo));
    memcpy(newnode->data.pdata, x->pdata, x->lenth);
     
    newnode->next = NULL;
    
    //队列为空的情况
    if (pq->tail == NULL)
    {
        pq->head = pq->tail = newnode;
    }
    else
    {
        pq->tail->next = newnode;
        pq->tail = newnode;//刷新尾结点
    }
    
    return ERR_COMMON_SUCCEED;
}

/**************************************************************************
    函数名称: QueuePop
    功能描述: 数据出队列 
    输入参数: IN Queue *pq            队列头
              IN QDataType x      待出列的数据
    输出参数: 无
    注 意 点: 出列的数据会从队列中删除, 队列是先进先出原则, 该函数删除的是头节点;
              数据内容的指针该函数会释放
***************************************************************************/
int QueuePop(IN Queue *pq)
{
    //出列必须保证队列不为空
    if ((NULL == pq) || (NULL == pq->head) || (NULL == pq->tail))
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }

    //当出列到只剩下一个元素,tail为野指针,需单独判断
    if (pq->head->next == NULL)
    {
        /* 先释放实际数据 */
        if (NULL != pq->head->data.pdata)
        {
            free(pq->head->data.pdata);
            pq->head->data.pdata = NULL;
        }
        
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else
    {
        QNode* next = pq->head->next;
        
        if (NULL != pq->head->data.pdata)
        {
            free(pq->head->data.pdata);
            pq->head->data.pdata = NULL;

        }
        
        free(pq->head);
        pq->head = next;
    }
    return ERR_COMMON_SUCCEED;
}

/**************************************************************************
    函数名称: QueueIsEmpty
    功能描述: 判断队列是否为空 
    输入参数: IN Queue *pq            队列头
    输出参数: 无
    注 意 点: 
***************************************************************************/
int QueueIsEmpty(IN Queue *pq)
{
    if (NULL == pq)
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }
    
    if (NULL != pq->head)
    {
        return BOOL_FALSE;
    }
    
    return BOOL_TRUE;
}

/**************************************************************************
    函数名称: QueueSize
    功能描述: 获取队列中元素个数 
    输入参数: IN Queue *pq            队列头
    输出参数: 无
    注 意 点: 
***************************************************************************/
int QueueSize(IN Queue *pq, OUT size_t *size)
{
    if ((NULL == pq) || (NULL == size))
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }

    QNode* cur = pq->head;
    *size = 0;
    
    while (NULL != cur)
    {
        (*size)++;
        cur = cur->next;
    }
 
    return ERR_COMMON_SUCCEED;
}

/**************************************************************************
    函数名称: QueueFront
    功能描述: 获取队头元素 
    输入参数: IN Queue *pq               队列头
    输出参数: OUT QDataType *data        队列头元素内容
    注 意 点: 
***************************************************************************/
int QueueFront(IN Queue *pq, OUT QDataType *data)
{
    if ((NULL == pq) || (NULL == pq->head) || (NULL == data))
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return ERR_COMMON_INVALID_PARAM;
    }
    
    memcpy(data, &pq->head->data, sizeof(QDataType));
    
    return ERR_COMMON_SUCCEED;
}

/**************************************************************************
    函数名称: QueueBack
    功能描述: 获取队尾元素 
    输入参数: IN Queue *pq               队列头
    输出参数: OUT QDataType *data        队列尾元素内容
    注 意 点: 
***************************************************************************/
int QueueBack(IN Queue *pq, OUT QDataType *data)
{
    if ((NULL == pq) || (NULL == pq->head) || (NULL == pq->tail))
    {
        Printf("[MSG_CTRL]Invalid parameter");
        return -1;
    }

    memcpy(data, &pq->tail->data, sizeof(QDataType));
    
    return ERR_COMMON_SUCCEED;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值