数据结构第七章:队列的学习

目录

  • 一.队列的概念和结构
  • 二.队列头文件实现
  • 三.队列具体函数实现
    • 1.队列的初始化
    • 2.队列的销毁
    • 3.入队列
    • 4.出队列
    • 5.返回队列头的数据
    • 6.返回队列尾的数据
    • 7.队列大小的获取
    • 8.判断队列是否为空

一.队列的概念和结构

队列是遵循先进先出原则的线性数据结构,仅可以在队尾插入元素,仅可以在队头删除数据。

队列主要分为顺序队列和链式队列两种结构。

顺序队列一般由数组结构来实现,类似于顺序表的方式实现。需要在空间不足时,及时申请空间。

链表队列一般由链表结构来实现,无需担心空间的浪费。

下面队列将用链表的形式来实现。因为顺序表实现的队列,空间大小不足时,扩容不方便。并且在出队函数中,顺序表实现时需要将头节点后面的所有节点前挪一个位置。效率较低。

二.队列头文件实现

c 复制代码
typedef int QDataType;
typedef struct QueueNode
{
  struct QueueNode *next;
  QDataType data;
}QNode;
typedef struct Queue
{
  QNode* head;
  QNode* tail;
}Queue;
//队列的初始化
void QueueInit(Queue *pq);
//队列的销毁
void QueueDestory(Queue *pq);
//入队列
void QueuePush(Queue*pq,QDataType x);
//出队列
void QueuePop(Queue* pq);
//返回队列头的数据
QDataType QueueFront(Queue* pq);
//返回队列尾的数据
QDataType QueueBack(Queue* pq);
//得出队列的大小
int QueueSize(Queue *pq);
//判断队列是否为空
bool QueueEmpty(Queue *pq);

三.队列具体函数实现

1.队列的初始化

c 复制代码
void QueueInit(Queue *pq)
{
  assert(pq);
  pq->head=pq->tail=NULL;
}

上述代码的具体解释:首先排除pq指针为空的情况,否则后续会错误的使用空指针,接下来的初始化就是将头节点和尾节点置为NULL即可。

2.队列的销毁

c 复制代码
void QueueDestory(Queue *pq)
{
  assert(pq);
  QNode* cur=pq->head;
  while(cur)
  {
    QNode* next=cur->next;
    free(cur);
    cur=next;
  }
  pq->head=pq->tail=NULL;
}

上述代码的具体解释:首先排除pq指针为空情况,防止后续对其错误使用。创建一个临时指针变量保存数据的头节点。当该临时变量不为空时,进入while循环释放cur临时变量的空间,并且让cur指针后移,出while循环之后将phead和tail置为NULL即可。

3.入队列

c 复制代码
void QueuePush(Queue* pq,QDataType x)
{
  assert(pq);
  QNode* newnode=(QNode*)malloc(sizeof(QNode));
  if(newnode==NULL)
  {
    printf("malloc fail");
    exit(-1);
  }
  newnode->data=x;
  newnode->next=NULL;
  if(pq->tail==NULL)
  {
    pq->head=pq->tail=newnode;
  }
  else
  {
    pq->tail->next=newnode;
    pq->tail=newnode;
  }
}

上述代码的具体解释:首先利用malloc函数申请空间节点,用于存储队列的新数据。当申请的节点为空时打印申请失败的错误信息。申请成功时,先插入对应的数据为随后的入队列做好准备。如果tail指针为空,说明队列是空的,此时只需要将新申请的节点赋值给头和尾节点即可。如果tail指针不为空,说明队列不为空,此时需要将新申请的节点接到尾节点的后面,最后更新尾节点位置即可。

4.出队列

c 复制代码
void QueuePop(Queue* pq)
{
  assert(pq);
  assert(pq->head);
  if(pq->head->next==NULL)
  {
    free(pq->head)
    pq->head=pq->tail=NULL;
  }
  else
  {
    QNode* next=pq->head->next;
    free(pq->head);
    pq->head=next;
  }
}

上述代码的具体解释:当队列只有一个节点时,直接释放该节点,之后将其置为NULL。当队列不是一个节点时,先保存头节点的下一个节点,随后释放头节点,最后将保存的节点更新为新的头节点。

5.返回队列头的数据

c 复制代码
QDataType QueueFront(Queue* pq)
{
  assert(pq);
  assert(pq->head);
  return pq->head->data;
}

上述代码的具体解释:首先排除pq指针为空的情况,再排除head指针为空的情况,防止队列为空,最后返回头指针的数据即可。

6.返回队列尾的数据

c 复制代码
QDataType QueueBack(Queue *pq)
{
  assert(pq);
  assert(pq->head);
  return pq->tail->data;
}

上述代码的具体解释:首先排除pq指针为空的情况,再排除head指针为空的情况,防止队列为空,最后返回尾指针的数据即可。

7.队列大小的获取

c 复制代码
int QueueSize(Queue* pq)
{
  assert(pq);
  int size=0;
  QNode* cur=pq->head;
  while(cur)
  {
    ++size;
    cur=cur->next;
  }
  return size;
}

上述代码的具体解释:首先排除pq指针为空的情况,随后创建一个变量用于存储队列的大小。随后创建一个结构体指针变量用于存储头节点。当cur临时指针变量不为NULL时进入循环,size变量在一次一次的循环中不断自增直到cur变量为空。最后返回size的值即可。

8.判断队列是否为空

c 复制代码
bool QueueEmpty(Queue* pq)
{
  assert(pq);
  return pq->head==NULL;
}

上述代码的具体解释:返回值为bool类型,先排除pq指针为空的情况,当表达式pq->head为空时,返回真。当表达式为假时,返回假。

相关推荐
zz0723202 小时前
数据结构 —— 并查集
java·数据结构
CQ_YM2 小时前
数据结构之排序
c语言·数据结构·算法·排序算法
小股虫3 小时前
Redis数据结构底层深度解析:写入与读取的高效逻辑
数据结构·redis·bootstrap
CoderYanger3 小时前
C.滑动窗口-求子数组个数-越短越合法——3134. 找出唯一性数组的中位数
java·开发语言·数据结构·算法·leetcode
ndzson3 小时前
从前序与中序遍历序列构造二叉树 与
数据结构·算法
今天你TLE了吗3 小时前
LeeCode Hot100随机链表的复制 java易懂题解
java·数据结构·链表
山峰哥3 小时前
现代 C++ 的最佳实践:从语法糖到工程化思维的全维度探索
java·大数据·开发语言·数据结构·c++
别动哪条鱼4 小时前
FFmpeg AVFormatContext 分配函数详解
数据结构·ffmpeg·音视频
CoderYanger4 小时前
C.滑动窗口-求子数组个数-越短越合法——LCP 68. 美观的花束
java·开发语言·数据结构·算法·leetcode