数据结构--链式队列

来源:互联网 发布:淘宝三包图片 编辑:程序博客网 时间:2024/05/27 06:16

1. 简介

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

2. 源码

[LinkQueue.c]/*********************************************************************************************************** @file     LinkQueue.c* @author   SY* @version  V1.0.1* @date     2016-9-12 13:08:32* @IDE      V4.70.0.0* @Chip     STM32F407VE* @brief    链式队列源文件********************************************************************************************************** @attention*   队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,*   允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点:先进先出(FIFO)。* -------------------------------------------------------------------------------------------------------* 版本:V1.0.1     修改人:SY      修改日期:2016-9-12 13:08:40* * 1、增加链式队列的遍历。* -------------------------------------------------------------------------------------------------------   *   ** **********************************************************************************************************//***********************************************************************************************************                                           Private Includes**********************************************************************************************************/#include "utils.h"#include "LinkQueue.h"/***********************************************************************************************************                                           Private define**********************************************************************************************************//***********************************************************************************************************                                           Private typedef**********************************************************************************************************//***********************************************************************************************************                                           Private constants**********************************************************************************************************//***********************************************************************************************************                                           Private macro**********************************************************************************************************//***********************************************************************************************************                                           Private variables**********************************************************************************************************//***********************************************************************************************************                                           Private function prototypes**********************************************************************************************************//***********************************************************************************************************                                           Private functions**********************************************************************************************************//*********************************************************************************************************** Function Name : CreateLinkQueue* Description   : 创建链式队列(内存空间由内部提供、动态内存)* Input         : None* Output        : None* Return        : None**********************************************************************************************************/LINK_QUEUE_TypeDef *CreateLinkQueue( void ){    /* 生成头指针 */    LINK_QUEUE_TypeDef *pHead = (LINK_QUEUE_TypeDef *)calloc(1,sizeof(LINK_QUEUE_TypeDef));    if (pHead == NULL)    {        return NULL;    }    /* 生成头结点 */    LINK_QUEUE_NODE_TypeDef *pNode = (LINK_QUEUE_NODE_TypeDef *)calloc(1,sizeof(LINK_QUEUE_NODE_TypeDef));    if (pNode == NULL)    {        return NULL;    }    pNode->data = NULL;    pNode->next = NULL;    pHead->front = pNode;    pHead->rear = pNode;    return pHead;}/*********************************************************************************************************** Function Name : LinkQueueIsEmpty* Description   : 链式队列是否为空* Input         : None* Output        : None* Return        : None**********************************************************************************************************/DATA_STRUCT_STATUS_ENUM LinkQueueIsEmpty( LINK_QUEUE_TypeDef *pHead ){    if (pHead == NULL)    {        return STATUS_DATA_STRUCT_UNDEFINED;    }    if (pHead->front->next == NULL)    {        return STATUS_DATA_STRUCT_TRUE;    }    else    {        return STATUS_DATA_STRUCT_FALSE;    }}/*********************************************************************************************************** Function Name : ClearLinkQueue* Description   : 清空链式队列* Input         : None* Output        : None* Return        : None**********************************************************************************************************/void ClearLinkQueue( LINK_QUEUE_TypeDef *pHead ){    if (pHead != NULL)    {        LINK_QUEUE_NODE_TypeDef *oldNode = NULL;        while (pHead->front->next != NULL)        {            oldNode = pHead->front->next;            pHead->front->next = oldNode->next;            oldNode->next = NULL;            if (oldNode->data != NULL)            {                free(oldNode->data);                oldNode->data = NULL;            }            free(oldNode);            oldNode = NULL;                     }        pHead->rear = pHead->front;    }}/*********************************************************************************************************** Function Name : DestoryLinkQueue* Description   : 销毁链式队列* Input         : None* Output        : None* Return        : None**********************************************************************************************************/void DestoryLinkQueue( LINK_QUEUE_TypeDef **pHead ){    LINK_QUEUE_TypeDef *this = *pHead;    if (this != NULL)    {        ClearLinkQueue(this);        if (this->front != NULL)        {            /* 释放头结点 */            free(this->front);            this->front = this->rear = NULL;            /* 释放头指针 */            free(this);            *pHead = NULL;        }    }}/*********************************************************************************************************** Function Name : PushLinkQueue* Description   : 链式队列入队* Input         : None* Output        : None* Return        : None**********************************************************************************************************/DATA_STRUCT_STATUS_ENUM PushLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataIn, uint32_t dataSize ){    if (pHead == NULL)    {        return STATUS_DATA_STRUCT_UNDEFINED;    }    /* 增加新节点 */    LINK_QUEUE_NODE_TypeDef *pNode = (LINK_QUEUE_NODE_TypeDef *)calloc(1,sizeof(LINK_QUEUE_NODE_TypeDef));    if (pNode == NULL)    {        return STATUS_DATA_STRUCT_FALSE;    }    pNode->next = NULL;     if (pHead->front->next == NULL)    {        pHead->rear = pHead->front;    }    pHead->rear->next = pNode;    pHead->rear = pNode;    /* 存储用户数据 */    pNode->data = (void *)calloc(1,dataSize);    if (pNode->data == NULL)    {        return STATUS_DATA_STRUCT_FALSE;    }       memcpy(pNode->data,dataIn,dataSize);    return STATUS_DATA_STRUCT_TRUE;}/*********************************************************************************************************** Function Name : PopLinkQueue* Description   : 链式队列出队* Input         : None* Output        : None* Return        : None**********************************************************************************************************/DATA_STRUCT_STATUS_ENUM PopLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize ){    if (pHead == NULL)    {        return STATUS_DATA_STRUCT_UNDEFINED;    }    if (LinkQueueIsEmpty(pHead) == STATUS_DATA_STRUCT_TRUE)    {        return STATUS_DATA_STRUCT_FALSE;    }    /* 出队时,头指针始终指向头结点,出队头结点后面的节点 */    LINK_QUEUE_NODE_TypeDef *oldNode = pHead->front->next;      pHead->front->next = oldNode->next;    oldNode->next = NULL;    if (pHead->front->next == NULL)    {        pHead->rear = pHead->front;    }    DATA_STRUCT_STATUS_ENUM isDataOK = STATUS_DATA_STRUCT_FALSE;    if (oldNode->data != NULL)    {        memcpy(dataOut,oldNode->data,dataSize);        free(oldNode->data);        oldNode->data = NULL;        isDataOK = STATUS_DATA_STRUCT_TRUE;    }    free(oldNode);    oldNode = NULL;    return isDataOK;}/*********************************************************************************************************** Function Name : GetLinkQueueElement* Description   : 获取链式队列元素* Input         : None* Output        : None* Return        : None**********************************************************************************************************/DATA_STRUCT_STATUS_ENUM GetLinkQueueElement( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize ){    if (pHead == NULL)    {        return STATUS_DATA_STRUCT_UNDEFINED;    }    if (LinkQueueIsEmpty(pHead) == STATUS_DATA_STRUCT_TRUE)    {        return STATUS_DATA_STRUCT_FALSE;    }    /* 出队时,头指针始终指向头结点,出队头结点后面的节点 */    DATA_STRUCT_STATUS_ENUM isDataOK = STATUS_DATA_STRUCT_FALSE;    LINK_QUEUE_NODE_TypeDef *oldNode = pHead->front->next;          if (oldNode->data != NULL)    {        memcpy(dataOut,oldNode->data,dataSize);        isDataOK = STATUS_DATA_STRUCT_TRUE;    }    return isDataOK;}/*********************************************************************************************************** Function Name : TraverseLinkQueue* Description   : 遍历链式队列* Input         : None* Output        : None* Return        : None**********************************************************************************************************/void TraverseLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize,\        void (*show_CallBack)( void *dataOut ) ){    LINK_QUEUE_TypeDef queue = *pHead;    LINK_QUEUE_NODE_TypeDef *pNode = queue.front->next;    while (pNode != NULL)    {        memcpy(dataOut,pNode->data,dataSize);        if (show_CallBack)        {            show_CallBack(dataOut);        }        pNode = pNode->next;    }}/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/
[LinkQueue.h]/*********************************************************************************************************** @file     LinkQueue.h* @author   SY* @version  V1.0.0* @date     2016-9-1 11:17:33* @IDE      V4.70.0.0* @Chip     STM32F407VE* @brief    链式队列头文件********************************************************************************************************** @attention** **********************************************************************************************************//***********************************************************************************************************                                           Define to prevent recursive inclusion**********************************************************************************************************/#ifndef __LINKQUEUE_H#define __LINKQUEUE_H/***********************************************************************************************************                                           Exported Includes**********************************************************************************************************//***********************************************************************************************************                                           Exported define**********************************************************************************************************//***********************************************************************************************************                                           Exported types**********************************************************************************************************/typedef struct tagLINK_QUEUE_NODE_TypeDef{    void *data;    struct tagLINK_QUEUE_NODE_TypeDef *next;}LINK_QUEUE_NODE_TypeDef;typedef struct{    LINK_QUEUE_NODE_TypeDef *front;    LINK_QUEUE_NODE_TypeDef *rear;}LINK_QUEUE_TypeDef;/***********************************************************************************************************                                           Exported constants**********************************************************************************************************//***********************************************************************************************************                                           Exported macro**********************************************************************************************************//***********************************************************************************************************                                           Exported variables**********************************************************************************************************//***********************************************************************************************************                                           Exported functions**********************************************************************************************************/LINK_QUEUE_TypeDef *CreateLinkQueue( void );DATA_STRUCT_STATUS_ENUM LinkQueueIsEmpty( LINK_QUEUE_TypeDef *pHead );void ClearLinkQueue( LINK_QUEUE_TypeDef *pHead );void DestoryLinkQueue( LINK_QUEUE_TypeDef **pHead );DATA_STRUCT_STATUS_ENUM PushLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataIn, uint32_t dataSize );DATA_STRUCT_STATUS_ENUM PopLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize );DATA_STRUCT_STATUS_ENUM GetLinkQueueElement( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize );void TraverseLinkQueue( LINK_QUEUE_TypeDef *pHead, void *dataOut, uint32_t dataSize,\        void (*show_CallBack)( void *dataOut ) );#endif/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/

备注:


1、本文以链表形式实现队列,使用动态内存存储链表节点及数据域。
2、采用泛型编程思想,不限制数据类型。数据可以是基本数据类型也可以是复合数据类型。

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 : TestLinkQueue* Description   : 测试链式队列* Input         : None* Output        : None* Return        : None**********************************************************************************************************/void TestLinkQueue( void ){    LINK_QUEUE_TypeDef *pHead = CreateLinkQueue();    if (pHead == NULL)    {        printf("内存分配失败!\r\n");        return;    }    {        for (uint8_t i=1; i<=3; ++i)        {            PushLinkQueue(pHead, &i, sizeof(i));        }        uint8_t dataBuff = 0;        printf("----- STATR -----\r\n");        TraverseLinkQueue(pHead, &dataBuff, sizeof(dataBuff), PrintSeqQueue);        printf("----- E N D -----\r\n\r\n");    }    {        uint8_t dataBuff = 0;        PopLinkQueue(pHead,&dataBuff, sizeof(dataBuff));        printf("出队元素:%d\r\n",dataBuff);        printf("----- STATR -----\r\n");        TraverseLinkQueue(pHead, &dataBuff, sizeof(dataBuff), PrintSeqQueue);        printf("----- E N D -----\r\n\r\n");    }}/*********************************************************************************************************** Function Name : main* Description   : 入口函数* Input         : None* Output        : None* Return        : None**********************************************************************************************************/int main( void ){    InitSystem();    TestLinkQueue();    while (1);  }

打印结果:


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

出队元素:1
—– STATR —–
2
3
—– E N D —–

0 0
原创粉丝点击