Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据结构与算法(七)——队列结构

数据结构与算法(七)——队列结构

作者头像
拉维
发布于 2022-04-19 02:14:55
发布于 2022-04-19 02:14:55
1K02
代码可运行
举报
文章被收录于专栏:iOS小生活iOS小生活
运行总次数:2
代码可运行

今天来聊队列结构,队列的特点是先进先出

如上图所示,在队列头部出队列,在对列尾部入队列。在队列的结构中,有四个要素:队列头、队列尾、队列长度、队列内容。

一、顺序队列的队列假溢出问题

如上图所示,front表示队头,rear表示队尾

  • 图(a)表示,一个空队列,此时front和rear均指向初始的0号位置;
  • 图(b)表示,将c1、c2、c3三个元素入队,此时front指针并未移动,rear指针移动到了3号位;
  • 图(c)表示,c1、c2俩元素相继出队,此时队尾指针rear并未移动,队首front指针移动到了2号位;
  • 图(d)表示入队与出队同时进行的操作,c4、c5、c6相继入队,c3、c4相继出队,此时front移动到了4号位,rear指针按道理应该移动到6号位,但是我们这个队列没有6号位,所以rear指针就停留在了队列的最末端

如上图中的(d)所示,在顺序队列中,队列的长度是在一开始就确定了的,当rear指针指向了队列的最末端、front指针指向4号位置的时候,如果此时又有一个新的元素需要加入到队列当中来,那咋办呢?没地儿存了啊。front指针之前的0号位~3号位这4个位置相当于就空出来了并且也不能被重复利用了。这就是所谓的顺序队列的假溢出问题。那么如何解决这个问题呢?我们可以采用“循环队列”的思想来解决顺序队列的假溢出问题

如上图所示,就是一个“循环队列”,“循环队列”是在逻辑上将队列的头跟尾拼在一起,队列头指针和队列尾指针都是在这个“循环队列”中循环移动的。也就是说,队尾指针在移动到队列的最末端的时候,此时再有新元素入队的话,队尾指针就会移动到队列最开始的位置。这样的话就解决了顺序队列的假溢出问题。

需要注意的是,“循环队列”是一个思想,那么我们如何在代码中去实现“循环队列”思想呢?方法就是取余运算。比如,队列长度是length,那么队尾指针就可以通过rear%length来获取。

现在已经实现了队列空间的循环利用。我们接下来继续给队列入队和出队。

比如我们一开始那个(d)场景,其队尾指针rear就可以移动到如下的0号位置:

然后继续将c7、c8、c9、c10进行入队,如下图所示:

此时,队首指针front还停留在4号位置没有变,队尾指针rear也已经移动到了4号位置,此时该队列就处于满队的状态。可以看到,满队和空队的时候rear指针和front指针都是指向同一个位置。显然,只通过rear==front是不足以区分到底是满队还是空队的。那么如何进一步加以区分呢?答案就是留白一个占位空间,即牺牲一个存储单元

如上图所示,红框内就是一个预留的占位空间,这样的话,rear指针指向占位空间的时候,就说明队列已满;而不是rear指针指向当前的front的时候才会队满

需要注意的是,占位空间是一直跟随着队首指针在变化的,占位空间一直是在队首指针的前一个位置

这样的话,当rear==front的时候就代表空队,(rear-front+max_size)%max_size==max_size - 1代表满队。

上面的这一整个流程,我们可以通过下面这张图来更为形象地解释一下:

  • (a)一开始处于空队的时候,front和rear都处于0号位置;
  • (b)紧接着a、b、c相继入队,front处于0号位置没有改变,rear移动到了3号位置;
  • (c)然后a出队,rear停留在了3号位置没有变,front移动到了1号位置;
  • (d1)然后d、e、f、g相继入队,front依旧停留在2号位置,rear也移动到了1号位置,此时队满。
  • (d2)我们发现,空队和满队都是rear==front,无法区分,因此我们牺牲掉了一个存储单元,这个存储单元不存储任何内容,只是作为满队的一个标识,该存储单元会随着队首指针而移动(一直是队首指针的上一个循环位置),当队尾指针rear指向该存储单元的时候,就代表满队了

二、顺序队列

所谓顺序队列,指的就是用顺序存储的方式来实现的队列结构

首先来看一下顺序队列的结构设计

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include <stdbool.h>

#define Queue_Size 10 // 队列的长度

// 操作的状态
typedef enum : int {
  Success,
  Error,
} Status;

// 元素类型
typedef int ElementType;

// 顺序队列的结构
typedef struct SequentialQueue {
  int front; // 队列头指针
  int rear; // 队列尾指针
  ElementType datas[Queue_Size]; // 队列中的数据。注意,此时就已经开辟了一段连续的存储空间了。
} SequentialQueue;

我上面有提到,一个队列的结构设计需要有四个要素:队首、队尾、长度、队列内容。在这里,front和rear这两个首尾指针的取值就是下标,因此它俩包含了长度要素,所以,这里的顺序队列的结构中是包含了front、rear、datas这三个要素。

接下来看一下如何初始化一个空队列

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 1,初始化一个空队列
Status initSequentialQueue(SequentialQueue *queue) {
  queue->front = 0;
  queue->rear = 0;
  return  Success;
}

这里只需要将rear和front这两个索引给初始化为0就可以了,不需要初始化队列的内存空间,因为在队列结构体创建的时候就已经开辟了一段连续的内存空间,不需要再次重复创建

队列的置空代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 2,将队列清空
Status clearSequentialQueue(SequentialQueue *queue) {
  queue->rear = queue->front = 0;
  return Success;
}

将队列置空的时候,也只需要将front和rear这两个索引置为0即可,不需要清理内存空间,因为顺序队列的内存空间是一开始创建的时候就开辟好的一段连续的内存空间,这段连续的内存空间只有在队列被销毁的时候才会清理。而我们这里是将队列清空,因此是没有必要处理内存空间的,即便是有新元素入队,那么也就覆盖原来的空间即可

队列的判空代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 3,队列的判空
bool isQueueEmpty(SequentialQueue queue) {
  return queue.front == queue.rear;
}

获取队列的当前长度代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 4,队列的当前长度
int queueLength(SequentialQueue queue) {
  return (queue.rear - queue.front + Queue_Size) % Queue_Size;
}

这里所说的队列的长度,指的是队列中的有效元素的个数。

获取队头的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 5,队头元素
Status getQueueHead(SequentialQueue queue, ElementType *head) {
  // 队列为空,则返回Error
  if (queue.rear == queue.front) {
    return Error;
  }
  
  // 队列非空,则获取对应元素
  *head = queue.datas[queue.front];
  return Success;
}

入队代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 6,入队
Status addElement(SequentialQueue *queue, ElementType element) {
  // 如果队满,则返回错误
  if ((queue->rear - queue->front + Queue_Size) % Queue_Size == Queue_Size - 1) {
    return Error;
  }
  
  // 如果队未满,则入队
  queue->datas[queue->rear] = element;
  queue->rear = (queue->rear + 1) % Queue_Size;
  
  return Success;
}

这里说两点。

  1. 第一点就是判断队满的条件。由于队列中是有一个辅助用的占位空间的,所以满队时的队列长度会比队列空间的长度要小1
  2. 第二点是,队列的rear指针指向的是下一次入队的时候的位置,而不是当前队尾元素的位置,所以有新元素要入队的时候,直接给queue->datas[queue->rear]赋值即可,但是赋完值之后需要将rear向后移一位。

出队代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 7,出队
Status removeElement(SequentialQueue *queue, ElementType *removedElement) {
  // 如果顺序栈为空,则直接返回错误
  if (queue->rear == queue->front) {
    return Error;
  }
  
  // 如果顺序栈不为空,则直接出队
  *removedElement = queue->datas[queue->front];
  queue->front = (queue->front + 1) % Queue_Size;
  return Success;
}

队列遍历打印的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 8,循环打印
Status printSequentialQueue(SequentialQueue queue) {
  // 队列为空
  if (queue.rear == queue.front) {
    printf("该队列为空\n");
    return Success;
  }
  
  // 队列不为空
  printf("队列信息如下:\n");
  int i = queue.front;
  while (i != queue.rear) {
    printf("%d\n", queue.datas[i]);
    i = (i + 1) % Queue_Size;
  }
  return Success;
}

三、链式队列

所谓链式队列,指的是用链式存储的方式实现一个队列结构

我们之前在讲链表的时候,讲到通过头结点的设计可以简化链表元素增删改查的操作,可以减少一些判断逻辑。而链式队列也需要有一个头结点的设计,这个头结点的作用就类似于顺序队列中的那个预留的空白占位空间

在链式队列中,当队列的首尾指针都指向链表的头结点的时候,说明是空队列。每一次入队,队列的尾结点都指向最新入队的节点。每一次出队,队列的首元结点就会被移除。注意,front指针永远是指向链式队列的头结点,而队列中真正的第一个元素(即队首)是front指向的头结点之后的那个首元结点

我上面提到,队列的结构设计要考虑四个要素:队首、队尾、队列长度和队列的内容。而在现在这个链式队列中,front指针(指向头结点)和rear指针(指向尾结点)就将队列长度和队列内容给覆盖掉了。

链式队列的结构设计代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include <stdbool.h>

// 操作的状态
typedef enum : int {
  Success,
  Error,
} Status;

// 元素类型
typedef int ElementType;

// 节点类型
typedef struct Node {
  ElementType data; // 数据域
  struct Node *next; // 指针域
} Node;

// 链式队列的结构
typedef struct {
  struct Node *front; // 指向头结点
  struct Node *rear; // 指向尾结点
} LinkedQueue;

接下来看一下队列的初始化代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 1,初始化队列
Status initLinkedQueue(LinkedQueue *queue) {
  // 新建一个节点,并初始化新节点的指针域为NULL
  struct Node *headNode = malloc(sizeof(Node));
  if (!headNode) {
    return Error;
  }
  headNode->next = NULL;
  
  // 将新节点设置为链式队列的头结点
  queue->front = queue->rear = headNode;
  return Success;
}

初始化一个链式队列的时候,需要创建一个头结点,然后让front和rear都指向头结点,此时队列为空

接下来看一下销毁队列的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 2,销毁队列
Status destroyQueue(LinkedQueue *queue) {
  // 如果队列不存在,或者队列为空,则直接销毁
  if (!queue) {
    return Error;
  }
  
  // 如果队列存在,则依次遍历销毁
  struct Node *tempNode;
  while (queue->front != queue->rear) {
    tempNode = queue->front;
    queue->front = queue->front->next;
    free(tempNode);
  }
  queue = NULL;
  return Success;
}

销毁队列的原则就是将队列中的所有节点的内存空间都释放,其他的什么都不需要关心。

清空队列的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 3,清空队列
Status clearLinkedQueue(LinkedQueue *queue) {
  // 如果队列不存在,则直接返回错误
  if (!queue) {
    return Error;
  }
  
  // 如果队列存在,则首尾指针指向头结点,其他的节点都销毁
  // 记录首元结点
  struct Node *trueFirstNode = queue->front->next;
  // 将尾结点指向头结点
  queue->rear = queue->front;
  // 依次销毁首元结点及其之后的所有节点
  struct Node *tempNode;
  while (trueFirstNode) {
    tempNode = trueFirstNode;
    trueFirstNode = trueFirstNode->next;
    free(tempNode);
  }
  // 将头结点的指针域置空
  queue->front->next = NULL;
  return Success;
}

需要注意的是,销毁队列和清空队列是不一样的。销毁队列是直接将所有节点销毁即可,但是清空队列需要考虚的东西要多一些。

清空队列的时候,需要保留头结点,并且将front和rear指针都指向头结点,并且需要将头结点的指针域置空;还需要将原来的首元结点以及其后面的所有节点都给销毁

队列的判空

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 4,队列的判空
bool isLinkedQueueEmpty(LinkedQueue queue) {
  return queue.front == queue.rear;
}

判空的逻辑很简单,就是看front和rear是否指向同一个节点。因为front指针的指向永远是头结点,而在队列中的所有元素都出队了之后,rear也会指向头结点;如果队列中还有其他元素,那么rear就不会指向头结点

入队代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 5,入队
/*
 入队就是将新节点插入到链表尾部
 */
Status addElement(LinkedQueue *queue, ElementType element) {
  // 如果队列不存在则报错
  if (!queue) {
    return Error;
  }
  
  // 新建一个节点,并初始化指针域为空
  struct Node* tailNode = malloc(sizeof(Node));
  if (!tailNode) {
    return Error;
  }
  tailNode->data = element;
  tailNode->next = NULL;
  
  //将新节点插入到链表尾部
  queue->rear->next = tailNode;
  queue->rear = tailNode;
  return Success;
}

入队其实就是将新建的节点放到链表的尾部

出队代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 6,出队
/*
 出队就是找到当前的首元结点,然后将首元结点给移除。
 有一种特殊情况需要判断,就是当前即将删除的节点是尾结点的时候,此时需要将rear指针指向头结点
 */
Status removeElement(LinkedQueue *queue, ElementType *removedElement) {
  // 队列不存在则报错
  if (!queue) {
    return Error;
  }
  
  // 空队列则报错
  if (queue->rear == queue->front) {
    return Error;
  }
  
  // 记录当前的首元结点
  struct Node *trueFirstNode = queue->front->next;
  // 将当前的首元结点改为原首元结点的下一个节点
  queue->front->next = trueFirstNode->next;
  // 记录移除的节点数据
  *removedElement = trueFirstNode->data;
  // 如果当前移除的是链式队列中的最后一个节点元素,那么移除之后队列就空了,此时还需要将rear指针指向头结点
  if (queue->rear == trueFirstNode) {
    queue->rear = queue->front;
  }
  // 释放原来的首元结点的内存
  free(trueFirstNode);
  return Success;
}

出队,实际上就是移除单向链表的首元结点,因此,出队的时候需要对队列进行判空;并且还要兼容一种特殊情况,就是当前即将删除的节点是尾结点的时候,此时需要将rear指针指向头结点

获取队列长度的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 7,获取队列长度
int queueLength(LinkedQueue queue) {
  // 空队列
  if (queue.front == queue.rear) {
    return 0;
  }
  
  // 队列非空
  int length;
  struct Node *tempNode;
  for (length = 1, tempNode = queue.front->next; tempNode != queue.rear; length++, tempNode = tempNode->next);
  return length;
}

思路就是自首元结点开始遍历计数,一直到尾结点为止。

获取队列头元素以及遍历打印队列的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 8,获取头元素
Status getTrueFirstElement(LinkedQueue queue, ElementType *trueFirstElement) {
  // 队列为空则返回错误
  if (queue.front == queue.rear) {
    return Error;
  }
  
  // 队列非空则返回首元结点
  *trueFirstElement = queue.front->next->data;
  return Success;
}

// 9,遍历打印队列
void printLinkedQueue(LinkedQueue queue) {
  // 队列为空
  if (queue.rear == queue.front) {
    printf("该队列为空\n");
    return;
  }
  
  // 队列非空
  printf("队列信息如下:\n");
  struct Node *tempNode = queue.front->next;
  while (tempNode) {
    printf("%d\n", tempNode->data);
    tempNode = tempNode->next;
  }
}

以上。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【数据结构】线性表(九)队列:链式队列及其基本操作(初始化、判空、入队、出队、存取队首元素)
队列是一种操作受限的线性表,对于它的所有插入都在表的一端进行,所有的删除(以至几乎所有的存取)都在表的另一端进行,且这些操作又都是按照先进先出(FIFO)的原则进行的。进行删除的一端称为队头(front),进行插入的一端称为队尾(rear)。没有元素的队列称为空队列(简称空队)。
Qomolangma
2024/07/30
3270
【数据结构】线性表(九)队列:链式队列及其基本操作(初始化、判空、入队、出队、存取队首元素)
数据结构(4):队列(上)
队列(Queue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。这和我们日常生活中的排队是一致的,最早排队的也是最早离队的,其操作特性是先进先出(First In Last Out,FIFO)。
不可言诉的深渊
2021/04/16
6290
队列的基本操作(顺序队列、循环队列、链式队列)
队列也是一种线性表,是一种先进先出的线性结构。队列只允许在表的一端进行插入(入队)、删除(出队)操作。允许插入的一端称为队尾,允许删除的一端称为队头。 队列的基本操作包括:
全栈程序员站长
2022/08/25
4.3K0
队列的基本操作(顺序队列、循环队列、链式队列)
【Java数据结构学习笔记之三】Java数据结构与算法之队列(Queue)实现
  本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型   队列同样是一种特殊的线性表,其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out)。我们把向队列中插入元素的过程称为入队(Enqueue),删除元素的过程称为出队(Dequeue)并把允许入队的一端称为队尾,允许出的的一端称为队头,没有任何元素的队列则称为空队。
Angel_Kitty
2018/04/09
1.3K0
【Java数据结构学习笔记之三】Java数据结构与算法之队列(Queue)实现
【数据结构】队列(C++)
设立一个队头指针front,一个队尾指针rear,分别指向队头元素和队尾元素,rear-front为元素个数。
半生瓜的blog
2023/05/13
6360
【数据结构】队列(C++)
重学数据结构(三、队列)
和上一篇的栈相反,队列(queue)是一种先进先出(First In First Out, FIFO)的线性表。
三分恶
2020/09/01
3890
重学数据结构(三、队列)
【算法与数据结构】队列的实现详解
front和rear都指向-1,表示队列中没有数据。size为0,表示队列中没有元素。
学习起来吧
2024/03/16
3530
【算法与数据结构】队列的实现详解
C++数据结构——队列「建议收藏」
(1)队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构;
全栈程序员站长
2022/08/22
3.2K0
C++数据结构——队列「建议收藏」
数据结构-栈和队列
栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。如下所示:
黄规速
2022/04/14
5870
数据结构-栈和队列
数据结构(五)队列
队列(Queue)是一种限定在表的一端(队尾)进行插入,另一端(队首)进行删除的线性表,具有先进先出(First in first out,FIFO)的特点。
xbai921031
2022/05/25
1550
数据结构(五)队列
看看你对队列的了解有多少?
1.1队列概念及基本操作 队列(Queue) 简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。在队列中把插入数据元素的一端称为队尾(Rear),删除数据元素的一端称为队头(Front )。向队尾插人元素称为进队或入队,新元素人队后成为新的队尾元素; 从队列中删除元素称为离队或出队,元素出队后,其后续元素成为新的队头元素。 由于队列的插入和删除操作分别在队尾和队头进行,每个元素必然按照进人的次序离队,也就是说先进队的元素必然先离队,所以称队列为先进先出
Java学习
2018/04/17
8210
看看你对队列的了解有多少?
【自考】数据结构第三章,队列,期末不挂科指南,第4篇
这篇博客主要介绍一下队列的概念,并且采用C语言,编写两种存储实现方式:顺序存储和链式存储,当然还有常规的队列基本操作的实现算法
梦想橡皮擦
2020/01/24
4060
数据结构与算法:队列
队列(Queue)就像是排队买票的人群。想象一下你去电影院看电影,人们在售票窗口形成一条线(队列)等待购票。队列遵循一个很重要的原则:先来先服务(First In, First Out,简称FIFO)。这意味着最先到达并排队的人将会是第一个买到票并离开队列的人,随后到达的人则依次排在队伍的后面,等待买票。
用户11029103
2024/03/19
1460
数据结构与算法:队列
数据结构:栈&队列
栈的顺序存储称为顺序栈,它是利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶的位置。
HLee
2020/12/29
8850
数据结构:栈&队列
3-2 队列
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行删除操作的端称为队头 ,进行插入操作的端称为队尾。
TeeyoHuang
2019/07/02
4100
3-2 队列
PHP数据结构-队列的相关逻辑操
在逻辑结构中,我们已经学习了一个非常经典的结构类型:栈。今天,我们就来学习另外一个也是非常经典的逻辑结构类型:队列。相信不少同学已经使用过 redis 、 rabbitmq 之类的缓存队列工具。其实,数据库、程序代码,这些都可以实现队列的操作,就和栈一样,队列也是有其特定的规则,只要符合这个规则,它就叫做队列。
硬核项目经理
2021/04/22
4330
PHP数据结构-队列的相关逻辑操
数据结构3——linuxC(栈和队列)
demo1顺序栈 #include <stdio.h> #define SEQ_STACK_SIZE 10 // 顺序栈数据节点 struct seq_stack{ int data; }; // 顺序栈下标 int g_n; // 入栈(压栈) void stack_push(int new_data, struct seq_stack *s); // 出栈(弹栈) int stack_pop(int *pop_data, struct seq_stack *s); // 显示顺序栈中
天天Lotay
2022/12/02
6510
数据结构3——linuxC(栈和队列)
【Python数据结构系列】☀️《队列(顺序队列、链式队列、双端队列)》——知识点讲解+代码实现☀️
队列,和栈一样,也是一种对数据的"存"和"取"有严格要求的**线性存储结构。 **
天道Vax的时间宝藏
2021/08/12
1.1K0
数据结构与算法 -链式队列
链式式队列是用链表表示的队列,它是限制仅 在表头删除和表尾插入的单链表。显然仅有单链表的头指针不便于在表尾做插入操作,为此再增加一个尾指针,指向链表的最后一个结点。
越陌度阡
2020/11/26
3770
数据结构与算法 -链式队列
队列的基本操作
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。 其实我们来对比栈,栈的特点是只能在一端进行操作的,而队列是一端插入一端删除。
兰舟千帆
2022/07/16
4660
队列的基本操作
推荐阅读
相关推荐
【数据结构】线性表(九)队列:链式队列及其基本操作(初始化、判空、入队、出队、存取队首元素)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验