在阅读本文前, 请先阅读以下一篇文章.
一. 队列的定义
队列是一种特殊的线性表, 其只允许在一端(队尾)进行插入数据操作, 在另一端(队首)进行删除数据操作,队列中的数据元素遵循先进先出 FIFO (First In First Out) 的原则.
二. 队列各种接口的实现
此处的队列采用单链表的结构实现, 因为如果使用顺序表的结构, 出队列时在顺序表头上出数据,效率相对较低.
typedef int QDataType;
typedef struct QueueNode
{
QDataType data; // 数据域
struct QueueNode* next; // 指针域
}QNode;
typedef struct Queue
{
QNode* head; // 队首
QNode* tail; // 队尾
int size; // 队列有效数据个数
}Queue;
1. 初始化
创建好结构体后, 对其进行初始化.
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
2. 销毁
当不再使用队列时, 将链表从队首到队尾逐个节点销毁.
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* curr = pq->head;
while (curr) {
QNode* temp = curr->next;
free(curr);
curr = temp;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
3. 队尾入队列
入队, 即将数据元素从队尾插入队列中.
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
perror("malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL) {
assert(pq->tail == NULL);
pq->head = pq->tail = newnode;
} else {
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
4. 队首出队列
出队, 即将数据元素从队首弹出.
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL) {
free(pq->head);
pq->head = pq->tail = NULL;
} else {
QNode* temp = pq->head->next;
free(pq->head);
pq->head = temp;
}
pq->size--;
}
5. 返回队列中有效数据个数
返回队列中有效元素个数.
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
6. 检测队列是否为空
检测队列是否为空.
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
7. 获取队首元素
获取队首元素.
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
8. 获取队尾元素
获取队尾元素.
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
三. 队列的源码
Queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
QDataType data; // 数据域
struct QueueNode* next; // 指针域
}QNode;
typedef struct Queue
{
QNode* head; // 队首
QNode* tail; // 队尾
int size; // 队列有效数据个数
}Queue;
// 初始化
void QueueInit(Queue* pq);
// 销毁
void QueueDestroy(Queue* pq);
// 队尾入队列
void QueuePush(Queue* pq, QDataType x);
// 队首出队列
void QueuePop(Queue* pq);
// 返回队列中有效数据个数
int QueueSize(Queue* pq);
// 检测队列是否为空
bool QueueEmpty(Queue* pq);
// 获取队首元素
QDataType QueueFront(Queue* pq);
// 获取队尾元素
QDataType QueueBack(Queue* pq);
Queue.c
#include "Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* curr = pq->head;
while (curr) {
QNode* temp = curr->next;
free(curr);
curr = temp;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
perror("malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL) {
assert(pq->tail == NULL);
pq->head = pq->tail = newnode;
} else {
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL) {
free(pq->head);
pq->head = pq->tail = NULL;
} else {
QNode* temp = pq->head->next;
free(pq->head);
pq->head = temp;
}
pq->size--;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
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;
}