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 —–