循环队列的基本运算实现
数据结构-队列基本运算的实现及其应用

数据结构-队列基本运算的实现及其应用篇一数据结构-队列基本运算的实现及其应用一、队列的基本概念队列是一种特殊的数据结构,它遵循先进先出(FIFO)的原则,即先进入队列的元素先出队列。
在队列中,新元素被添加到队列的末尾,而删除操作总是发生在队列的开头。
队列常用于解决各种问题,如处理事件、任务调度、缓冲处理等。
二、队列的基本操作队列的基本操作包括入队(enqueue)、出队(dequeue)、查看队首元素(peek)和判断队列是否为空。
入队操作:向队列的末尾添加一个新元素。
这个操作的时间复杂度通常为O(1),可以通过在队列的末尾添加元素来实现。
出队操作:删除队列开头的元素并返回它。
这个操作的时间复杂度通常为O(1),可以通过移除队列开头的元素来实现。
查看队首元素:返回队列开头的元素但不删除它。
这个操作的时间复杂度通常为O(1),可以通过返回队列开头的元素来实现。
判断队列是否为空:检查队列是否包含任何元素。
这个操作的时间复杂度通常为O(1),可以通过比较队列的长度和0来实现。
三、队列的实现队列可以通过不同的数据结构来实现,如数组、链表和循环列表等。
在这里,我们将介绍使用数组和链表来实现队列的基本操作。
使用数组实现队列使用数组实现队列时,我们需要保留一个空间来跟踪队列的开头和结尾。
通常,我们使用两个指针,一个指向队列的开头,另一个指向队列的结尾。
当我们在队列中添加一个新元素时,我们将它添加到结尾指针所指向的位置,并将结尾指针向后移动一位。
当我们要删除一个元素时,我们只需将开头指针向后移动一位并返回该位置的元素即可。
使用链表实现队列使用链表实现队列时,我们通常使用一个头指针指向队首元素,一个尾指针指向队尾元素的下一个位置。
入队操作时,我们在尾指针的位置创建一个新节点,并将尾指针移动到下一个位置。
出队操作时,我们只需删除头指针指向的节点,并将头指针移动到下一个位置。
四、队列的应用队列在计算机科学中有着广泛的应用,下面列举几个常见的例子:事件处理:在多线程编程中,队列经常用于事件驱动的系统来传递事件或消息。
数据结构-第3章-队列

a
front
b
c
d
e
f
g
rear
3.2 队列的顺序存储及实现
在使用队列前,先初始化队列,此时,队列为空,队头指针 front和 队尾指针rear都指向队列的第一个位置,即front=rear=0,如图3.3 所示。
下标 0 1 2 3 4 5 6Байду номын сангаас7 8 9
3.3 队列的链式存储及实现
(2)判断队列是否为空。 int QueueEmpty(LinkQueue *Q) {
return Q->rear==Q->front;
}
//头尾指针相等队列为空
3.3 队列的链式存储及实现
(3)将元素x入队。先为新结点申请一个空间,然后将x赋给数据 域,并使原队尾元素结点的指针域指向新结点,队尾指针指向新结点, 从而将结点加入队列中。操作过程如图3.20所示。
3.2 队列的顺序存储及实现
(4)入队
int EnQueue(CirQueue *Q , DataType x)
{ if(QueueFull(Q)) printf(“Queue overflow”); else{ Q->data[Q->rear]=x; Q->rear=(Q->rear+1)%QueueSize; } }
3.3 队列的链式存储及实现
链式队列的类型描述如下:
/*结点类型定义*/
typedef struct QNode { DataType data; struct QNode * next; } QueueNode; /*队列类型定义*/ typedef struct { QueueNode * front; //队头指针
队列及其应用

可以看出:
☞ 尾指针 rear 已指到数组的最后一个元素,即 rear = maxlen-1,若这时入队,则产生“溢出”; ☞ 此时经过一定数量的出队后,头指针 front 可指 向队列的中间,即 数组的前面部分有闲置的空间
—— 这种有可用空间存在的溢出 称“假溢出” 问题:如何利用数组前面的可用空间?
解决的方法:将data[0] 看作是data[maxlen-1] 后的下 一个存储位置。 即:将向量空间看成是一个首尾相接的圆环。
并称这种向量为循环向量,存储在其中的队列称为 循环队列(Circular Queue)。
在循环队列中进行出队、入队操作时,头尾指针仍 要加1,朝前移动。只不过当头尾指针指向向量上界 (maxsize-1)时,其加1操作的结果是指向向量的下 界0。
队列的特点
☞ 根据队列的定义可知,最先入队的元素也是最先 出队。
☞ 特点:先进先出(FIFO) 也就是说,队列是一种先进先出 (First In Out)的线性表,简称为FIFO表。
出队列 a1 a2 a3 …………an 队头 front 队尾 rear
First
入队列
5.1 队列的基本概念
5.1.1 队列的定义
d
front
front
入队 队满
可见,队空与队满有相同的描述方式: 队空:Q->rear = Q->front 队满: Q->rear = Q->front
问题:如何区分队空与队满状态?
解决方法: (1) 设置一入队或出队标志,以区分最后一次操作是 入队还是出队。这样,当头尾两个指针相等时,由该 标志可以判断出满和空。 (2) 少用一个元素空间,即 将仅剩一个空位置时的状 态当作满状态,也就是不让rear 指针赶上 front 指针。
循环队列的插入算法

循环队列的插入算法循环队列是一种特殊的队列数据结构,它能够循环利用底层数组的空间。
插入元素是循环队列的一个基本操作,下面将详细介绍循环队列的插入算法。
循环队列由队头指针 front 和队尾指针 rear 组成,它们指向数组中的队头和队尾元素。
初始时,队头和队尾指针都指向数组的第一个位置,即 front = rear = 0。
为了避免队列为空和队列满时无法区分的情况,需要牺牲一个数组空间,使得循环队列的最大长度为数组长度减1、因此,当 rear 指针指向数组的最后一个位置时,如果再进行插入操作,rear指针将回到数组的第一个位置,形成循环。
以下是循环队列的插入算法的详细步骤:1. 首先判断循环队列是否已满,即判断 (rear + 1) % 数组长度是否等于 front。
如果相等,则表示循环队列已满,无法插入新元素。
如果不满足条件,执行步骤22. 将要插入的元素放入 rear 指针指向的位置,即 array[rear] = element。
3. 更新 rear 指针的位置,即 rear = (rear + 1) % 数组长度。
由于循环队列是循环利用数组空间的,所以需要使用取模运算来保证 rear指针可以循环回到数组的第一个位置。
4. 如果队列为空,则需要更新 front 指针的位置,即 front = rear。
这是由于循环队列为空时,front 和 rear 指针应该指向同一个位置。
否则,继续执行下一步。
5.插入操作完成。
下面是循环队列插入算法的伪代码:```function enqueue(element):if ((rear + 1) % array_length == front) thenreturn "Queue is full"elsearray[rear] = elementrear = (rear + 1) % array_lengthif (front == -1) thenfront = rearend ifend ifend function```以上就是循环队列的插入算法介绍,通过这一算法可以实现元素的插入操作。
实现循环队列的入队出队等基本操作

实现循环队列的入队出队等基本操作循环队列是一种特殊的队列数据结构,通过循环利用数组空间来实现入队和出队操作。
它的特点是队头和队尾可以在数组上循环移动,从而充分利用数组空间,提高队列的效率。
下面将详细介绍循环队列的实现。
1.定义循环队列的数据结构循环队列的数据结构由以下几个成员组成:-一个固定大小的数组,用于存储队列元素。
- 一个队头指针front,指向队列的第一个元素。
- 一个队尾指针rear,指向队列的最后一个元素的下一个位置。
2.初始化循环队列首先,我们需要在内存中分配一个固定大小的数组,并初始化队头和队尾指针为0。
```pythondef __init__(self, k: int):self.queue = [0] * kself.front = self.rear = 0```3.入队操作入队操作会在队尾插入一个新元素,并将队尾指针后移一位。
如果队列已满,则入队操作会失败。
```pythondef enqueue(self, value: int) -> bool:if self.isFull(:return Falseself.queue[self.rear] = valueself.rear = (self.rear + 1) % len(self.queue)return True```4.出队操作出队操作会删除队头元素,并将队头指针后移一位。
如果队列为空,则出队操作会失败。
```pythondef dequeue(self) -> bool:if self.isEmpty(:return Falseself.front = (self.front + 1) % len(self.queue)return True```5.判空操作判空操作会检查队头和队尾指针是否相等,如果相等则说明队列为空。
```pythondef isEmpty(self) -> bool:return self.front == self.rear```6.判满操作判满操作会检查队尾指针的下一位是否等于队头指针,如果相等则说明队列已满。
循环队列判空和判满条件

循环队列判空和判满条件循环队列是一种经常使用的数据结构,它具有环形的特点。
在实际应用中,判断循环队列的空和满条件非常重要,因为只有在了解了这些条件后,我们才能正确地对循环队列进行操作。
本文将介绍循环队列的判空和判满条件,并提供相应的代码示例。
一、循环队列的定义和基本操作循环队列是一种使用数组实现的队列,它的特点是充分利用数组空间,将队列头尾相连,形成一个环。
下面是循环队列的基本操作:1. 初始化:创建一个队列,并设置队列的头指针(front)和尾指针(rear)为0。
2. 入队操作:将元素插入到队列的尾部,并将尾指针(rear)向后移动一位。
3. 出队操作:删除队列的头部元素,并将头指针(front)向后移动一位。
4. 判空:当头指针(front)和尾指针(rear)相等时,表示队列为空。
5. 判满:当尾指针(rear)的下一位等于头指针(front)时,表示队列已满。
二、循环队列判空和判满条件的分析1. 判空条件对于判断循环队列是否为空,我们只需判断头指针(front)和尾指针(rear)是否相等即可。
如果相等,表示队列为空;反之,队列不为空。
2. 判满条件判断循环队列是否已满需要特殊处理。
当队列尾指针(rear)的下一位等于队列头指针(front)时,表示队列已满。
由于是循环队列,尾指针(rear)在移动时会环绕到数组的开头,因此我们需要通过模运算来计算下一位的位置。
三、循环队列判空和判满条件的代码实现(C++示例)```cpp#include<iostream>using namespace std;const int MaxSize = 100; // 循环队列的最大容量class CircularQueue {private:int queue[MaxSize]; // 队列数组int front; // 头指针int rear; // 尾指针public:CircularQueue() {front = rear = 0; // 初始化队列}// 入队操作void enqueue(int value) {if ((rear + 1) % MaxSize == front) {cout << "Queue is full. Unable to enqueue." << endl; return;}queue[rear] = value;rear = (rear + 1) % MaxSize;}// 出队操作void dequeue() {if (front == rear) {cout << "Queue is empty. Unable to dequeue." << endl; return;}int value = queue[front];front = (front + 1) % MaxSize;cout << "Dequeued element: " << value << endl; }// 判空操作bool isEmpty() {return front == rear;}// 判满操作bool isFull() {return (rear + 1) % MaxSize == front;}};int main() {CircularQueue queue;queue.enqueue(1);queue.enqueue(2);queue.enqueue(3);queue.dequeue();queue.dequeue();queue.dequeue();queue.dequeue();return 0;}```四、总结循环队列是一种常用的数据结构,因其能够充分利用数组空间并实现高效的入队和出队操作而被广泛应用。
任务5 进位制转换

任务5 进位制转换教学目标1、知识目标1)掌握队列的定义及基本运算;2)掌握循环队列、链队列基本运算的实现算法。
2、能力目标1)具有恰当的选择队列作为数据的逻辑结构、循环队列、链队列作为数据的存储结构的能力;2)具有应用队列解决实际问题的能力。
3、素质目标养成善于思考解决实际问题的良好习惯。
一、任务描述进位制转换包括B1进制数转换为B2进制数,十进制数转换为B进制数,B进制数转换为十进制数等,这里,我们仅讨论十进制数转换为B进制数。
十进制数转换为B进制数可分为:十进制整数转换为B进制整数和十进制纯小数转换为B进制纯小数两部分。
为完成整数部分的转换和纯小数部分的转换,需要弄清楚这两部分分别应该选择何种数据结构。
为此,我们来学习下面的相关知识。
二、相关知识(一)队列的定义及基本操作队列与栈一样都是运算受限的线性表,但与栈的限制不同。
1、队列的定义队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。
向队列中插入元素称为入队,从队列中删除元素称为出队。
(1)允许删除的一端称为队头。
(2)允许插入的一端称为队尾。
(3)当队列中没有元素时称为空队列。
(4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。
队列的修改是依先进先出的原则进行的。
新来的成员总是加入队尾(即不允许“加塞”),每次离开的成员总是队列头上的成员(不允许中途离队),即当前“最老的”成员离队。
例在队列中依次加入元素a1,a2,…,a n之后,a1是队头元素,a n是队尾元素。
退出队列的次序只能是a1,a2,…,a n。
2、队列的基本运算1)置空队:InitQueue (Q)构造一个空队列Q。
2)判队空:QueueEmpty (Q)若队列Q为空,则返回真值,否则返回假值。
3)判队满:QueueFull (Q)若队列Q为满,则返回真值,否则返回假值。
注意:此操作只适用于队列的顺序存储结构。
实用数据结构基础

第4章 队列
第4章 队列
知识点
队列的定义和特点 队列的存储实现及运算实现 队列的应用举例
难点
循环队列的特点及判断溢出的条件 利用队列的特点设计相关的应用问题
要求 熟练掌握以下内容: 熟练掌握以下内容:
队列的特点和基本运算 循环队列的特征和基本运算
了解以下内容: 了解以下内容:
队列运算的时间复杂性分析 队列的实际应用
(2)入队 int InQueue ( csequeue *q ,datatype x) { if (n= =MAXLEN) 队满" { printf ("队满"); 队满不能入队,返回0 return 0; // 队满不能入队,返回0 } else >rear=(q->rear+1 MAXLEN; { q->rear=(q->rear+1) % MAXLEN; >data[q->rear]=x; q->data[q->rear]=x; >n++; q->n++; 入队完成,返回1 return 1; // 入队完成,返回1 } }
4-1-2 队列的基本运算
(1)入队操作: InQueue(q,x) )入队操作: ( , ) 初始条件: 存在且未满. 初始条件:队q存在且未满. 存在且未满 操作结果:输入一个元素x到队尾 长度加1. 到队尾, 操作结果:输入一个元素 到队尾,长度加 . (2)出队操作: OutQueue(q,x) )出队操作: ( , ) 初始条件: 存在, 初始条件 队q存在,且非空. 存在 且非空. 操作结果:删除队首元素,长度减1. 操作结果:删除队首元素,长度减 . (3)读队头元素:ReadFront(q,x) )读队头元素: ( , ) 初始条件: 存在且非空. 初始条件: 队q存在且非空. 存在且非空 操作结果: 读队头元素,队列不变. 操作结果: 读队头元素,队列不变.
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
① 运算规则不同,线性表为随机存取,而栈是只允 许在一端进行插入和删除运算,因而是后进先出 表LIFO;队列是只允许在一端进行插入、另一端 进行删除运算,因而是先进先出表FIFO。
② 用途不同,线性表比较通用;堆栈用于函数调用、 递归和简化设计等;队列用于离散事件模拟、多 道作业处理和简化设计等。
循环队列的操作演示flash
队空:front==rear 队满:front==rear
初始状态
rear
J6
J5 5
4
0
J4
3
1
2
front
队空、队满无法判断:
1.另外设一个标志以区别 2.少用一个元素空间:
队空:front==rear 队满:(rear+1)%M==front
5
4
0
3
1
2
front rear
循环队列的基本运算实现
1)进队列算法 (1)检查队列是否已满,若队满,则溢出错误; (2)将新元素赋给队尾指针所指单元; (3)将队尾指针后移一个位置(即加1)。 2)出队列算法 (1)检查队列是否为空,若队空,则下溢错误; (2)取队首元素的值。 (3)将队首指针后移一个位置(即加1);
3.4.2 链队列
3.4.1 队列的定义
队列(Queue)也是一种运算受限的线性 表。它只允许在表的一端进行插入,而 在另一端进行删除。允许删除的一端称 为队头(front),允许插入的一端称为队 尾(rear)。
队列的修改是依先进先出的原则进行的。
队列的基本运算
1.初始化队列 InitQueue(&Q) 将队列Q设置成一个空队列。
front
J6
J
J4 2 J8
J9
rear
循环队列
队空:Q.front =Q. rear 队满: Q.front =(Q.rear + 1) % maxSize 入队: Q.rear = (Q.rear + 1) % maxSize 出队: Q.front = (front + 1) % maxSize; 求队长:(Q.rear-Q.front+maxSize)%maxSize
顺序队列的操作演示flash
❖ 为充分利用向量空间,克服上述假上 溢现象,可以将向量空间想象为一个首 尾相接的圆环,并称这种向量为循环向 量,存储在其中的队列称为循环队列 (Circular Queue)。
❖ 循环队列中进行出队、入队操作时,头 尾指针仍要加1,朝前移动。只不过当 头尾指针指向向量上界(QueueSize-1) 时,其加1操作的结果是指向向量的下 界0。
2.入队列 EnQueue(&Q,X) 将元素X插入到队尾中,也称“进队” ,“插入”。 3.出队列 DeQueue(&Q,&e) 将队列Q的队头元素删除,并用e返回其值,也称“退队”、“删除”。 4.取队头元素 GetHead(Q,&e) 得到队列Q的队头元素之值,并用e返回其值。 5.判队空 QueueEmpty(Q)
❖ 链队列示意图
*q q.front
null q.rear
非空队列
*q
q.front
q.rear
null
空队列
和顺序队列类似,我们也是将这两个指 针封装在一起,将链队列的类型 LinkQueue定义为一个结构类型:
typedef struct queuenode{ ElemType data; struct queuenode *next; }QueueNode;
判断队列Q是否为空,若为空返回1,否则返回0。
3.4.3 队列的顺序实现
#define MAXSIZE 100 typedef struct { ElemType data[MAXSIZE];
int front; int rear; }SqQueue;
在非空队列里,头指针始终指向队头元素,而尾指针 始终指向队尾元素的下一位置。
typedef struct{ QueueNode *front; QueueNode *rear;
}LinkQueue;
链队列的基本实现
队列的应用
➢ CPU资源的竞争问题。 ➢ 主机与外部设备之间速度不匹配的
问题。 ➢ 服务、排队问题
讨论(代本章小结)
线性表、栈与队的异同点
相同点:逻辑结构相同,都是线性的;都可以用顺 序存储或链表存储;栈和队列是两种特殊的线性 表,即受限的线性表(只是对插入、删除运算加 以限制)。