数据结构--顺序队列

1. 简介

队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点:先进先出(FIFO)。

2. 源码

[SeqQueue.c]

/*
*********************************************************************************************************
* @file     SeqQueue.c
* @author   SY
* @version  V1.0.2
* @date     2016-9-12 09:11:43
* @IDE      V4.70.0.0
* @Chip     STM32F407VE
* @brief    顺序队列源文件
*********************************************************************************************************
* @attention
*   队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,
*   允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点:先进先出(FIFO)。
* ---------------------------------------------------------
* 版本:V1.0.1     修改人:SY      修改日期:2016-9-1 09:59:09  
* 
* 1、修改队列头尾顺序,将“头部插入,尾部删除”修改为“尾部插入,头部删除”!
* -------------------------------------------------------------------------------------------------------
* 版本:V1.0.2     修改人:SY      修改日期:2016-9-12 09:12:17
* 
* 1、增加顺序队列的遍历。
* -------------------------------------------------------------------------------------------------------   
* 
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private Includes
*********************************************************************************************************
*/
#include "utils.h"
#include "SeqQueue.h"


/*
*********************************************************************************************************
*                                           Private define
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                           Private typedef
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private constants
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private macro
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private variables
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private function prototypes
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private functions
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Function Name : CreateSeqQueue
* Description   : 创建顺序队列(内存空间由外部提供、静态内存)
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void CreateSeqQueue( SEQUEUE_TypeDef *queuePtr, void *pBase, uint32_t lenth )
{
    queuePtr->basePtr = pBase;
    queuePtr->maxLenth = lenth;
    queuePtr->front = 0;
    queuePtr->rear = 0;
}

/*
*********************************************************************************************************
* Function Name : SeqQueueIsFull
* Description   : 顺序队列是否为满
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM SeqQueueIsFull( SEQUEUE_TypeDef *queuePtr )
{
    if (((queuePtr->rear + 1) % queuePtr->maxLenth) == queuePtr->front)
    {
        return STATUS_DATA_STRUCT_TRUE;
    }
    else
    {
        return STATUS_DATA_STRUCT_FALSE;
    }
}

/*
*********************************************************************************************************
* Function Name : SeqQueueIsEmpty
* Description   : 顺序队列是否为空
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM SeqQueueIsEmpty( SEQUEUE_TypeDef *queuePtr )
{
    if (queuePtr->front == queuePtr->rear)
    {
        return STATUS_DATA_STRUCT_TRUE;
    }
    else
    {
        return STATUS_DATA_STRUCT_FALSE;
    }
}

/*
*********************************************************************************************************
* Function Name : ClearSeqQueue
* Description   : 清空顺序队列
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void ClearSeqQueue( SEQUEUE_TypeDef *queuePtr )
{
    queuePtr->front = 0;
    queuePtr->rear = 0;
}

/*
*********************************************************************************************************
* Function Name : GetSeqQueueFront
* Description   : 获取顺序队列头节点
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
uint32_t GetSeqQueueFront( SEQUEUE_TypeDef *queuePtr )
{
    return queuePtr->front;
}

/*
*********************************************************************************************************
* Function Name : GetSeqQueueRear
* Description   : 获取顺序队列尾节点
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
uint32_t GetSeqQueueRear( SEQUEUE_TypeDef *queuePtr )
{
    return queuePtr->rear;
}

/*
*********************************************************************************************************
* Function Name : GetSeqQueueLenth
* Description   : 获取顺序队列长度
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
uint32_t GetSeqQueueLenth( SEQUEUE_TypeDef *queuePtr )
{
    return queuePtr->maxLenth;
}

/*
*********************************************************************************************************
* Function Name : PushSeqQueue
* Description   : 顺序队列入队
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM PushSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataIn,\
        void (*push_CallBack)( void *base, uint32_t offset, void *data ) )
{
    if (SeqQueueIsFull(queuePtr) == STATUS_DATA_STRUCT_TRUE)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }

    push_CallBack(queuePtr->basePtr, queuePtr->rear, dataIn);
    queuePtr->rear = (queuePtr->rear + 1) % queuePtr->maxLenth;

    return STATUS_DATA_STRUCT_TRUE;
}

/*
*********************************************************************************************************
* Function Name : PopSeqQueue
* Description   : 顺序队列出队
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM PopSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ) )
{
    if (SeqQueueIsEmpty(queuePtr) == STATUS_DATA_STRUCT_TRUE)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }

    pop_CallBack(queuePtr->basePtr, queuePtr->front, dataOut);
    queuePtr->front = (queuePtr->front + 1) % queuePtr->maxLenth;

    return STATUS_DATA_STRUCT_TRUE;
}

/*
*********************************************************************************************************
* Function Name : GetSeqQueueElement
* Description   : 获取顺序队列元素
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM GetSeqQueueElement( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ) )
{
    SEQUEUE_TypeDef queue = *queuePtr;

    return PopSeqQueue(&queue,dataOut,pop_CallBack);
}

/*
*********************************************************************************************************
* Function Name : GetSeqQueueDisposeDataRate
* Description   : 获取顺序队列未处理数据比例
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
uint8_t GetSeqQueueDisposeDataRate( SEQUEUE_TypeDef *queuePtr )
{
    uint32_t front = queuePtr->front;
    uint32_t rear = queuePtr->rear;
    uint32_t lenth = queuePtr->maxLenth;
    uint32_t diff = 0;

    if (rear >= front)
    {
        diff = rear - front;
    }
    else
    {
        diff = lenth + rear - front;
    }

    return ((float)diff / lenth * 100);
}

/*
*********************************************************************************************************
* Function Name : TraverseSeqQueue
* Description   : 遍历顺序队列
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void TraverseSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ),\
        void (*show_CallBack)( void *dataOut ) )
{
    SEQUEUE_TypeDef queue = *queuePtr;

    while ( PopSeqQueue(&queue, dataOut, pop_CallBack) == STATUS_DATA_STRUCT_TRUE)
    {
        if (show_CallBack)
        {
            show_CallBack(dataOut);
        }
    }
}


/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/
[SeqQueue.h]

/*
*********************************************************************************************************
* @file     SeqQueue.h
* @author   SY
* @version  V1.0.0
* @date     2016-4-15 14:04:44
* @IDE      V4.70.0.0
* @Chip     STM32F407VE
* @brief    顺序队列头文件
*********************************************************************************************************
* @attention
*
* 
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Define to prevent recursive inclusion
*********************************************************************************************************
*/
#ifndef __SEQQUEUE_H
#define __SEQQUEUE_H

/*
*********************************************************************************************************
*                                           Exported Includes
*********************************************************************************************************
*/



/*
*********************************************************************************************************
*                                           Exported define
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported types
*********************************************************************************************************
*/
typedef struct
{
    void *basePtr;
    uint32_t maxLenth;
    uint32_t front;
    uint32_t rear;
}SEQUEUE_TypeDef;

/*
*********************************************************************************************************
*                                           Exported constants
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported macro
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Function Name : PushSequeueU8_CallBack
* Description   : 顺序队列8Bit整型数据入队
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
__STATIC_INLINE void PushSeqQueueU8_CallBack( void *base, uint32_t offset, void *dataIn )
{
    uint8_t *dataPtr = dataIn;
    uint8_t *basePtr = base;

    basePtr[offset] = *dataPtr;
}

/*
*********************************************************************************************************
* Function Name : PopSequeueU8_CallBack
* Description   : 顺序队列8Bit整型数据出队
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
__STATIC_INLINE void PopSeqQueueU8_CallBack( void *base, uint32_t offset, void *dataOut )
{
    uint8_t *dataPtr = dataOut;
    uint8_t *basePtr = base;

    *dataPtr = basePtr[offset];
}

/*
*********************************************************************************************************
*                                           Exported variables
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported functions
*********************************************************************************************************
*/
void CreateSeqQueue( SEQUEUE_TypeDef *queuePtr, void *pBase, uint32_t lenth );
DATA_STRUCT_STATUS_ENUM SeqQueueIsFull( SEQUEUE_TypeDef *queuePtr );
DATA_STRUCT_STATUS_ENUM SeqQueueIsEmpty( SEQUEUE_TypeDef *queuePtr );
void ClearSeqQueue( SEQUEUE_TypeDef *queuePtr );
uint32_t GetSeqQueueFront( SEQUEUE_TypeDef *queuePtr );
uint32_t GetSeqQueueRear( SEQUEUE_TypeDef *queuePtr );
uint32_t GetSeqQueueLenth( SEQUEUE_TypeDef *queuePtr );
DATA_STRUCT_STATUS_ENUM PushSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataIn,\
        void (*push_CallBack)( void *base, uint32_t offset, void *data ) );
DATA_STRUCT_STATUS_ENUM PopSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ) );
DATA_STRUCT_STATUS_ENUM GetSeqQueueElement( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ) );
uint8_t GetSeqQueueDisposeDataRate( SEQUEUE_TypeDef *queuePtr );
void TraverseSeqQueue( SEQUEUE_TypeDef *queuePtr, void *dataOut,\
        void (*pop_CallBack)( void *base, uint32_t offset, void *data ),\
        void (*show_CallBack)( void *dataOut ) );

#endif
/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/

备注:


1、 本文实现的顺序队列,以数组为基本结构。将泛型编程思想贯穿始末,只提供操作队列的方法,不提供实际数据类型、存储空间、数组地址及长度。全部由被调函数指定,这样做虽然看上去更加复杂,实际上适用性非常强,可以移植到任何需要顺序队列的地方。

3. 测试

[main.c]
/*
*********************************************************************************************************
* Function Name : TestSeqQueue
* Description   : 测试顺序队列
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void PrintSeqQueue( void *data )
{
    uint8_t *temp = data;

    printf("%d\r\n",*temp);
}

/*
*********************************************************************************************************
* Function Name : TestSeqQueue
* Description   : 测试顺序队列
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void TestSeqQueue( void )
{
    const uint32_t MAX_QUEUE_NUMS = 10;
    static uint8_t s_queue[MAX_QUEUE_NUMS];
    SEQUEUE_TypeDef queue;

    CreateSeqQueue(&queue, s_queue, MAX_QUEUE_NUMS);

    {
        for (uint8_t i=1; i<=5; ++i)
        {
            PushSeqQueue(&queue, &i,PushSeqQueueU8_CallBack);
        }

        printf("----- STATR -----\r\n");
        uint8_t tempData = 0;
        TraverseSeqQueue(&queue, &tempData, PopSeqQueueU8_CallBack, PrintSeqQueue);
        printf("----- E N D -----\r\n\r\n");
    }

    {
        uint8_t tempData = 0;
        PopSeqQueue(&queue, &tempData,PopSeqQueueU8_CallBack);

        printf("----- STATR -----\r\n");
        TraverseSeqQueue(&queue, &tempData, PopSeqQueueU8_CallBack, PrintSeqQueue);
        printf("----- E N D -----\r\n\r\n");
    }

    {
        uint8_t tempData = 0;
        GetSeqQueueElement(&queue, &tempData,PopSeqQueueU8_CallBack);
        printf("读取元素:%d\r\n",tempData);

        printf("----- STATR -----\r\n");
        TraverseSeqQueue(&queue, &tempData, PopSeqQueueU8_CallBack, PrintSeqQueue);
        printf("----- E N D -----\r\n\r\n");
    }
}

/*
*********************************************************************************************************
* Function Name : main
* Description   : 入口函数
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
int main( void )
{
    InitSystem();

    TestSeqQueue();

    while (1);  
}

打印结果:


—– STATR —–
1
2
3
4
5
—– E N D —–

—– STATR —–
2
3
4
5
—– E N D —–

读取元素:2
—– STATR —–
2
3
4
5
—– E N D —–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值