数据结构队列
Posted 凛音Rinne
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构队列相关的知识,希望对你有一定的参考价值。
队列
一、为什么要学习队列
在排队系统中,顾客去拿自己号码顺序,先拿到的一定先被叫号。
这种先进先出FIFO(First In First Out)
的模式被称为队列
队列顾名思义,排队,按顺序进入,按顺序出去
🍎只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表
进行插入操作的一端称为队尾
,进行删除操作的一端称为队头
二、队列的接口
在这种线性表的类型,可以是定义数组来实现,也可以定义链表来实现。
二者如何抉择?
因为涉及到元素移动,显然数组会很麻烦,而链表就很简单,只需要指针移动就行
所以下面接口以链表实现队列
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QueueNode;
这样队列的定义还不能结束,代表一个队列,我们可能需要一头一尾,一个控制队头一个控制队尾
但每次定义一个队列的时候都要先定义两个变量很麻烦
所以我们定义一个结构体变量,一个指针记录队头,一个指针记录队尾
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
1. 队列初始化
头和尾都置空
//队列初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
2. 进队
🍬head为空链表:
🍬head不为空链表:
//进队
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
🍇进队测试:
void testqueue1()
{
Queue q;
//初始化队列
QueueInit(&q);
//进队
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
}
🍬测试结果可以看出,tail指针指在最后一个数据
3. 出队
队列的出队一定是头部先出队
🍬出队前先判断队列是否为空
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return (pq->head == NULL);
}
//出队
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* next = pq->head->next;
if (next == NULL)
{
pq->tail = NULL;
}
free(pq->head);
pq->head = next;
}
🍦测试用例:
void testqueue1()
{
Queue q;
//初始化队列
QueueInit(&q);
//进队
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePop(&q);
}
🍦测试结果:可以看出1先消失的
4. 销毁队列
一个标准的头删操作
但要注意删到最后的时候的操作
🍞这个时候要把tail置空不然就是个 野指针
🍞
//销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while(cur != NULL)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->tail = NULL;
pq->head = NULL;
}
🍙测试用例:
void testqueue1()
{
Queue q;
//初始化队列
QueueInit(&q);
//进队
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePop(&q);
QueueDestroy(&q);
}
🍙测试结果:head
和tail
都为空了
5. 打印队列中元素个数
//队列中数据个数
int QueueSize(Queue* pq)
{
assert(pq);
int n = 0;
QueueNode* cur = pq->head;
while (cur)
{
n++;
cur = cur->next;
}
return n;
}
这个比较简单,有手就行。
6. 找到队头或队尾数据
二者相似,也是有手就行。
//取到队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
//取到队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
🍙连带着打印队列中元素一起测试:
void testqueue1()
{
Queue q;
//初始化队列
QueueInit(&q);
//进队
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePop(&q);
//QueueDestroy(&q);
printf("%d\\n", QueueSize(&q));
printf("%d\\n", QueueFront(&q));
printf("%d\\n", QueueBack(&q));
}
🍙测试结果:
以上是关于数据结构队列的主要内容,如果未能解决你的问题,请参考以下文章