数据结构从入门到实战————队列
前言
在计算机科学与数据结构领域,队列(Queue) 是一种重要的线性数据结构,遵循“先进先出”(First In, First Out, 简称 FIFO)的原则。作为抽象数据类型的一种典型实现,队列通过限制数据的插入和删除位置,构建了一个有序、公平的数据处理模型,广泛应用于需要按序执行的计算场景。
栈的基本功能:
- 先进先出(FIFO)操作:队列遵循“最先进入的元素最先被访问或移除”的原则,插入操作(Enqueue)在队尾进行,删除操作(Dequeue)在队头执行,确保数据按到达顺序处理。
- 高效的入队与出队:入队和出队操作的时间复杂度均为 O(1),无需遍历或移动其他元素,适合高频率的数据流转场景。
- 队头访问支持:提供 Front 或 Peek 操作,可在不改变队列结构的前提下查看即将处理的元素,用于状态预判或条件控制。
- 动态容量扩展:基于循环数组或链表实现时,队列可动态调整容量,适应不确定规模的数据流入,避免内存浪费或溢出。
- 任务调度与缓冲能力:天然适用于管理待处理任务序列,如消息传递、打印任务排队、广度优先搜索(BFS)等需公平调度的场景。
综上所述,队列作为一种基础而高效的数据结构,以其严格的顺序性和简洁的操作接口,在系统设计与算法实现中发挥着关键作用。尽管其访问受限于两端操作,但正是这种特性使其在异步通信、资源调度和流程控制等领域表现出色。本文简要阐述了队列的核心机制与典型应用,旨在帮助读者掌握其基本原理。
正文开始
一、队列的概念以及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。
二、队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
2.1 定义队列的结构以及方法的声明
Queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Que;//初始化
void QueueInit(Que* pq);
//销毁
void QueueDestroy(Que* pq);//队尾插入
void QueueInsert(Que* pq, QDataType x);
//队头删除
void QueueDelete(Que* pq);//取头数据
QDataType QueueFront(Que* pq);
//取队尾数据
QDataType QueueBack(Que* pq);//队列是否为空
bool QueueEmpty(Que* pq);//取队列节点的个数
int QueueSize(Que* pq);
2.2 队列的初始化
Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"//初始化
void QueueInit(Que* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}
2.3 栈的销毁
//销毁
void QueueDestroy(Que* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
2.4 队尾插入节点
//队尾插入
void QueueInsert(Que* pq, QDataType x)
{assert(pq);//创建节点QNode* node = (QNode*)malloc(sizeof(QNode));if (node == NULL){perror("malloc fail!");return;}node->val = x;node->next = NULL;//开始插入节点if (pq->phead == NULL){pq->phead = pq->ptail = node;}else{pq->ptail->next = node;pq->ptail = node;}pq->size++;
}
2.5 队头删除
//队头删除
void QueueDelete(Que* pq)
{assert(pq);assert(pq->size > 0);//要判断是否只有节点if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
2.6 取队头数据
//取头数据
QDataType QueueFront(Que* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}
2.7 取队尾数据
//取队尾数据
QDataType QueueBack(Que* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}
2.7 判断队列是否为空
//队列是否为空
bool QueueEmpty(Que* pq)
{return pq->size == 0;
}
2.8 获取队列长度
//队列的数据个数
QDataType QueueSize(Que* pq)
{assert(pq);return pq->size;
}
测试结果如下:
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"int main()
{Que q;QueueInit(&q);QueueInsert(&q, 1);QueueInsert(&q, 2);QueueInsert(&q, 3);QueueInsert(&q, 4);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueueDelete(&q);}printf("\n");return 0;
}
码云链接如下:https://gitee.com/a-qian-c-language/data-structure.git