深入了解队列:探索FIFO数据结构及队列

简介: 深入了解队列:探索FIFO数据结构及队列

1.队列的概念及结构


队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)


入队列:进行插入操作。此端称为队尾


出队列:进行删除操作。此段称为队头

11.png假设入队:A B C D

那么出队:A B C D


2.队列的实现


队列也可以数组和链表的结构实现,使用链表的结构来实现更适合一些,因为使用数组的结构,出队列这个操作在数组头上出数据(届时会需要全体移动),效率会比较低


2.1项目文件规划


12.png

  • 头文件Queue.h:用来基础准备(常量定义,typedef),链表表的基本框架,函数的声明
  • 源文件Queue.c:用来各种功能函数的具体实现
  • 源文件test.c:用来测试功能是否有问题,进行基本功能的使用


2.2基本结构及各功能(Queue.h)


#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode//节点的结构体
{
  QDataType val;
  struct QueueNode* next;
}QNode;
typedef struct Queue
{
  QNode* phead;
  QNode* ptail;
  int size; //元素数量(空间换时间)
}Queue;
void QInit(Queue* q);//初始化
void QDestroy(Queue* q);//销毁
void QPush(Queue* q, QDataType x);//插入
void QPop(Queue* q);//删除
QDataType QBack(Queue* q);//返回最后一个节点数据
QDataType QFront(Queue* q);//返回第一个节点数据
bool QEmpty(Queue* q);//是否为空
int QSize(Queue* q);//元素数量

这两个结构体组合在一起,构成了队列数据结构的基本框架

  • QNode 结构体用于表示队列中的节点
  • Queue 结构体则用于管理整个队列的状态和属性
    这种设计使得队列的操作和功能得以清晰地表现和实现


2.3各功能具体实现(Queue.c)


初始化

void QInit(Queue* q)
{
  assert(q);
  q->phead = q->ptail = NULL;
  q->size = 0;
}
  • 将队列的头尾指针设置为 NULL,表示队列为空。
  • 将队列中元素的数量设置为 0,因为队列此时没有任何元素


插入

void QPush(Queue* q, QDataType x)
{
  assert(q);
  QNode* newnode = (QNode*)malloc(sizeof(QNode));
  assert(newnode);//防止没有开辟成功(当人有点杞人忧天了)
  newnode->val = x;
  newnode->next = NULL;
  if (q->phead == NULL)
  {
    q->phead = q->ptail = newnode;
  }
  else
  {
    q->ptail->next = newnode;
    q->ptail = newnode;
  }
  q->size++;
}

首先使用 assert 确保传入的队列指针 q 是有效的

为新节点 newnode 分配内存,并设置其值为 x,next 指针指向 NULL

如果队列为空(即头尾指针均为空),则将新节点同时设置为队列的头尾节点。

如果队列不为空,则将新节点连接到队列尾部,并更新尾指针 ptail 指向新的尾节点。

最后,增加队列的大小 size。


删除

void QPop(Queue* q)
{
  assert(q);
  assert(q->size > 0);
  QNode* next = q->phead->next;
  free(q->phead);
  q->phead = next;
  //当只有一个节点时:把  q->ptail = NULL;
  if (q->phead == NULL)
  {
    q->ptail = NULL;
  }
  q->size--;
}

首先使用 assert 确保传入的队列指针 q 是有效的,并且队列中有元素即(size > 0)

通过 next 指针将队列头部的下一个节点保存下来,以备后续更新

释放队列当前的头节点

更新队列的头指针为下一个节点(如果有的话)

如果删除节点后队列为空==(只有一个节点),则将尾指针 ptail 也设置为 NULL(一个节点时,二者指向同一个地址)==

最后,减少队列的大小 size


返回最后一个节点数据

QDataType QBack(Queue* q)
{
  assert(q);
  assert(q->ptail);
  return q->ptail->val;
}

返回第一个节点数据

QDataType QFront(Queue* q)
{
  assert(q);
  assert(q->ptail);
  return q->phead->val;
}

是否为空

bool QEmpty(Queue* q)
{
  assert(q);
  return q->size == 0;
}

节点数量

bool QEmpty(Queue* q)
{
  assert(q);
  return q->size == 0;
}

销毁

void QDestroy(Queue* q)
{
  QNode* cur = q->phead;
  while (cur)
  {
    QNode* next = cur->next;
    free(cur);
    cur = next;
  }
  q->phead = q->ptail = NULL;
  q->size = 0;
}

队列的内容也整理完毕了,下一次会为大家带来二叉树和堆的相关内容,感谢大家的支持!!!


目录
相关文章
|
14天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
17天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
初步认识栈和队列
初步认识栈和队列
58 10
|
1月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
20 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索栈和队列的无尽秘密
【用Java学习数据结构系列】探索栈和队列的无尽秘密
30 2
|
1月前
【数据结构】-- 栈和队列
【数据结构】-- 栈和队列
16 0
|
1月前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用
|
1月前
|
存储 C语言
栈和队列题目练习
栈和队列题目练习
16 0
|
1月前
|
存储 算法 Java
【用Java学习数据结构系列】用堆实现优先级队列
【用Java学习数据结构系列】用堆实现优先级队列
29 0
|
1月前
|
C语言
数据结构------栈(Stack)和队列(Queue)
数据结构------栈(Stack)和队列(Queue)
19 0