【数据结构学习记录8】——队列

一.概念

和栈相反,队列是一种先进先出(first in first out = FIFO)的结构。FIFO是单片机的FIFO吗?它是一种线性表,只允许在表的一端插入元素,另一端删除元素。在队列中,能插入的一端叫队尾,允许删除的一端叫队头

二.原理实现

1.节点

因为我们队列还是一种线性表,所以我们的队列的节点因该还是由两个部分构成:数据区指向下一个节点的指针
在这里插入图片描述

2.队列

如果要实现一个队列,我们只需要两个指针并指向它的队头和队尾就可以了。
它最好使用链式储存,因为它的队头会经常改变,如果采用顺序结构,可能会浪费空间或者频繁修改大量元素。
在初始化的时候,我们可以把队头队尾都指向同一个节点,且节点的指向的下一个节点为NULL
在这里插入图片描述

3.入队

对于入队,我们只需要将元素插入到队尾的后面,再把队尾指向它即可。
在这里插入图片描述

4.出队

保存队头指向的下一个节点的地址,记为地址A,把队头指向地址A的下一个节点,然后再free掉A就可以了。
在这里插入图片描述

5.销毁

销毁一个队列,只需要从队头开始,依次把所有的节点free

三.代码

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

#define OK      1
#define ERROR   0

typedef struct dataType{
    
    
    int data;
}dataType;

typedef struct nodeType{
    
    
    dataType data;
    struct nodeType *next;
}nodeType;

typedef struct queue{
    
    
    nodeType *head;
    nodeType *tail;
}queue;

queue* QueueInit(void);
int QueuePush(queue* q, dataType data);
int QueueGet(queue* q, dataType *datain);
int QueuePop(queue* q);
int QueueDistroy(queue *q);

int main()
{
    
    
    // 主函数内容随便改
    queue *Q = QueueInit();
    dataType test;
    int i = 0;
    for (i = 0; i < 5; ++i)
    {
    
    
        test.data = i;
        QueuePush(Q, test);
    }
    while(Q->head != Q->tail)
    {
    
    
        QueueGet(Q, &test);
        printf("%d\n", test.data);
        QueuePop(Q);
    }
    for (i = 5; i >= 0; --i)
    {
    
    
        test.data = i;
        QueuePush(Q, test);
    }
    while(Q->head != Q->tail)
    {
    
    
        QueueGet(Q, &test);
        printf("%d\n", test.data);
        QueuePop(Q);
    }
    return 0;
}

queue* QueueInit(void)
{
    
    
    queue* q = (queue*)malloc(sizeof(queue));
    nodeType* qhead = (nodeType*)malloc(sizeof(nodeType));
    // 动态生成一个队列和它里面的一个节点

    if (q != NULL && qhead != NULL)
    {
    
    
        qhead->next = NULL;
        qhead->data.data = -1;   //信息初始化
        q->head = qhead;    // 头尾都指向同一个节点
        q->tail = qhead;
        return q;
    }
    exit(0);
}

int QueuePush(queue* q, dataType datain)
{
    
    
    nodeType *node = (nodeType*)malloc(sizeof(nodeType));

    if (node != NULL)
    {
    
    
        node->data = datain;    // 更新节点数据
        node->next = NULL;
        q->tail->next = node;   // 更新队列
        q->tail = node;         // 跟新队尾指针
        return OK;
    }
    return ERROR;
}

int QueueGet(queue* q, dataType *datain)
{
    
    
    if (q->head != q->tail && q->head->next != NULL)
    {
    
    
        *datain = q->head->next->data;  // 获得头指针指向的节点
        return OK;
    }
    return ERROR;
}

int QueuePop(queue *q)
{
    
    
    nodeType *dnode = NULL;

    if(q->head != q->tail && q->head->next != NULL)
    {
    
    
        dnode = q->head;
        q->head = q->head->next;    // 将头指针指向现在头指针的下一个节点
        free(dnode);    // 释放空间
        return OK;
    }
    return ERROR;
}

int QueueDistroy(queue* q)
{
    
    
    nodeType *dnode = NULL;
    while(q->head != q->tail)   // 只要头不等于尾,队列就还有成员
    {
    
    
        dnode = q->head;
        q->head = q->head->next;
        free(dnode);    // 同理参考Pop
        return OK;
    }
    return ERROR;
}

猜你喜欢

转载自blog.csdn.net/u011017694/article/details/109446565