队列
只允许在一端进行插入数据,在另一端进行删除数据操作的特殊线性表,队列具有先进先出,后进后出的性质。插入数据在队尾插入,删除数据在队头删除。插入数据的操作叫做入队列,删除数据的操作叫做出队列。队列可以取到队头的数据和队尾的数据。
队列的实现
队列的实现有很多种方法,顺序表、单链表、双向带头循环链表等等。顺序表不太好,出队列需要挪动数据,使用单链表。声明一个结构体,有三个成员变量,是两个指针,一个指向队头,一个指向队尾;一个是整型变量,记录队列元素个数。
队列有什么操作?初始化、入队列,判断队列是否为空、出队列、取队头数据、取队尾数据、队列元素个数、销毁。
List.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int QDataType;
// 单链表节点
typedef struct QueueNode
{
QDataType x;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
// 标记队头和队尾
QueueNode* head;
QueueNode* tail;
int size;
}Queue;
// 初始化
void QueueInit(Queue* pq);
// 入队列
void QueuePush(Queue* pq, QDataType x);
// 判断队列是否为空
bool QueueEmpty(Queue* pq);
// 出队列
void QueuePop(Queue* pq);
// 取队头数据
QDataType QueueFront(Queue* pq);
// 取队尾数据
QDataType QueueBack(Queue* pq);
// 队列元素个数
int QueueSize(Queue* pq);
// 销毁
void QueueDestroy(Queue* pq);
初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
入队列
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
// 申请节点,初始化节点数据
QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
node->x = x;
node->next = NULL;
// 如果没有数据,空队列,改队头和队尾
if (pq->head == NULL)
{
pq->head = pq->tail = node;
}
// 该队尾指向
else
{
pq->tail->next = node;
pq->tail = node;
}
pq->size++;
}
判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
出队列
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head);
// 只剩一个节点
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
// 删除队头数据,记录队头的下一个节点
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
取队头数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->x;
}
取队尾数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->x;
}
队列元素个数
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
销毁
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
// 从队头到队尾,依次释放节点
while (cur != NULL)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
}
队列的使用场景
队列可以使用在排队的情况,在银行办理业务的时候,先取号,那张表示会告诉前面还有多少人,即队列元素个数-1。 柜台叫号,按顺序叫人,从队头出队列。层序遍历也会用上队列。(后面二叉树的时候讲)
出队列顺序
出队列的顺序只跟入队列顺序有关,先进先出,后进后出。