实验5 循环队列的实现

合集下载

实验五 队列的应用(参考答案)

实验五 队列的应用(参考答案)

实验五、队列的应用一、实验原理:一种“先进先出”(FIFO---First In First Out)的数据结构:即插入在队尾一端进行,而删除在队头进行。

键盘缓冲区问题:设计算法实现模拟键盘缓冲区问题。

假设有两个进程同时存在于一个应用程序之中,第一个进程连续在屏幕上显示字符“X”,第二个进程不断检查键盘上是否有输入,若有则读入用户键入的字符,将其保存到键盘缓冲区之中。

程序约定当用户键入一个逗号“,”,则表示第一进程结束,系统开始显示那些在键盘缓冲区中的字符;接着继续执行第一个进程,即,在屏幕上显示字符“X”;当用户输入“;”的时候,刚结束整个程序。

算法提示:为了充分利用缓冲区的空间往往将缓冲区设计成循环队列的结构,并为循环队列结构的缓冲区设置一个队首指针和一个队尾指针。

每输入法一个字符到缓冲区中,就将尾指针后移,链入缓冲区的循环队列之中;每输出一个字符号,就将队头指针前移,将它从缓冲队列中删除。

参考代码:/*键盘缓冲区问题*/#define MAXSIZE 20#define TRUE 1#define FALSE 0#include "stdio.h"#include "conio.h"#include "dos.h"typedef char elemtype;typedef struct{elemtype elem[MAXSIZE];int front, rear;}queuetype;int enque(queuetype *s, elemtype x) /*数据入队列*/{if (( s->rear+1)%MAXSIZE==s->front ) /*队列已满*/return (FALSE);else{s->rear=(s->rear+1) % MAXSIZE;s->elem[s->rear]=x;return(true);}}elemtype delqueue (queuetype *s ) /*数据出队列*/{if (s-front==s->rear) /*队列为空*/return(NULL);else /*队列非空*/{s->front=(s->front+1)%MAXSIZE;return(s->elem[s->front]);}}main(){char ch1,ch2;queuetype *p;int t,f;p=(queuetype *)malloc(sizeof(queuetype));p->front=0;p->rear=0;while(1) /*开始交替执行*/{while(1) /*第一个进程的执行*/{if(kbhit()) /*检测是否有键盘输入*/{ch1=bdos(7,0,0); /*中断调用,键入字符存入ch1*/f=enqueue( p, ch1 ); /*字符入循环队列*/if ( f== FALSE ){printf(" The queue is already full !\n");break;}}if ( ch1==';' || ch1==',' )break; /*第一个进程正常结束情况*/printf("X"); /*执行第一个进程*/}ch2=delqueue(p);while( ch2 != NULL ){putchar(ch2); /*在屏幕上显示输入缓冲区中的内容*/ch2=delqueue(p); /*字符出队列*/}getchar(); /*为看清屏幕内容, 在此暂停, 按回车继续if (ch1==';'||f==FALSE) /*程序结束*/break;else /*继续执行*/ch1=''; /*先置空ch1*/}}。

循环队列是什么结构

循环队列是什么结构

循环队列是什么结构引言:在计算机科学领域中,队列是一种简单而常见的数据结构,它按照先进先出(FIFO)的原则管理数据。

循环队列是队列的一种特殊形式,将队列的首尾连接起来,形成一个环。

本文将详细介绍循环队列的定义、实现和应用。

一、循环队列的定义循环队列是一种通过环形缓冲区实现的线性数据结构,具有固定大小。

它包含一个数组,用于存储数据元素,以及两个指针front和rear,分别指向队列的头部和尾部。

特点:1. 队列为空时,front和rear指向同一个位置;2. 队列满时,front和rear指向相邻位置;3. 队列长度为数组的长度减1。

二、循环队列的实现1. 初始化:创建一个空数组,并将front和rear指针初始化为0。

2. 入队操作:将元素插入rear指针指向的位置,然后将rear指针右移一位。

如果rear指针超过数组边界,则将rear指针重置为0。

3. 出队操作:将front指针指向的元素返回,并将front指针右移一位。

如果front指针超过数组边界,则将front指针重置为0。

4. 队列判空:如果front和rear指向同一个位置,则队列为空。

5. 队列判满:如果rear指针的下一个位置是front指针,则队列为满。

三、循环队列的优势相比于普通队列,循环队列具有以下几个优势:1. 优化了空间利用:循环队列通过环形缓冲区的方式实现,充分利用了数据存储空间,避免了普通队列数组一旦填满就无法再存入元素的问题。

2. 提高了入队和出队的效率:循环队列通过指针的移动实现元素的插入和删除,无需移动整个队列,并且时间复杂度为O(1),相比于普通队列的O(n)效率更高。

3. 简化了队列的操作:循环队列可以自动调整指针的位置,无需移动整个队列,更加简洁高效。

四、循环队列的应用循环队列在实际应用中具有广泛的用途,下面列举了其中几个常见的应用场景:1. 生产者消费者模型:循环队列可以用来实现线程间的数据传递,生产者线程将数据入队,消费者线程从队列中取出数据进行处理。

顺序循环队列实验报告

顺序循环队列实验报告

一、实验目的1. 理解顺序循环队列的概念和原理。

2. 掌握顺序循环队列的初始化、入队、出队等基本操作。

3. 通过编程实现顺序循环队列,并验证其功能。

二、实验原理顺序循环队列是一种利用一维数组实现队列的存储结构。

它将一维数组看作是首尾相连的循环结构,队列的头部和尾部在数组的两端。

顺序循环队列的特点是:队列满时,头指针和尾指针相差一个数组的长度;队列空时,头指针和尾指针相等。

顺序循环队列的基本操作如下:1. 初始化:创建一个顺序循环队列,并设置头指针和尾指针。

2. 入队:将元素插入队列尾部。

3. 出队:从队列头部删除元素。

4. 判断队列是否为空或满。

三、实验内容1. 创建顺序循环队列类。

2. 实现顺序循环队列的初始化、入队、出队等基本操作。

3. 编写测试代码,验证顺序循环队列的功能。

四、实验步骤1. 创建顺序循环队列类,定义队列长度、头指针、尾指针等属性。

2. 实现顺序循环队列的初始化方法,初始化头指针和尾指针。

3. 实现顺序循环队列的入队方法,判断队列是否已满,如果未满,将元素插入队列尾部,并更新尾指针;如果已满,则提示队列已满。

4. 实现顺序循环队列的出队方法,判断队列是否为空,如果为空,则提示队列已空;如果未空,则从队列头部删除元素,并更新头指针。

5. 编写测试代码,创建顺序循环队列实例,执行入队和出队操作,验证顺序循环队列的功能。

五、实验结果与分析1. 初始化顺序循环队列```pythonclass CircularQueue:def __init__(self, size):self.queue = [None] sizeself.head = 0self.tail = 0self.count = 0self.maxsize = size```2. 入队操作```pythondef enqueue(self, item):if self.count == self.maxsize:print("Queue is full")else:self.queue[self.tail] = itemself.tail = (self.tail + 1) % self.maxsizeself.count += 1```3. 出队操作```pythondef dequeue(self):if self.count == 0:print("Queue is empty")else:item = self.queue[self.head]self.queue[self.head] = Noneself.head = (self.head + 1) % self.maxsize self.count -= 1return item```4. 测试代码```pythondef test_circular_queue():queue = CircularQueue(5)print("Enqueue 1 to 5:")for i in range(1, 6):queue.enqueue(i)print(queue.queue)print("Dequeue 1 to 5:")for _ in range(5):print(queue.dequeue())print(queue.queue)test_circular_queue()```实验结果分析:通过测试代码,我们可以看到顺序循环队列在初始化、入队和出队操作时都能正确执行。

循环队列实验报告心得与体会

循环队列实验报告心得与体会

循环队列实验报告心得与体会循环队列是数据结构中一个非常经典的概念,相对于其他队列结构,循环队列可以优化存储空间的使用,减少空间的浪费。

循环队列的操作也比较高效,能够快速执行入队和出队操作。

本次实验,我们对循环队列结构进行了深入的了解与实践,更深刻地认识到了数据结构的重要性。

在实验中,我们首先对循环队列的基本概念进行了学习,通过查阅相关资料和教材,我们了解到循环队列是一种环形的特殊队列,其队尾指针在达到数组的末尾时,再从数组的第一个位置开始存储数据,如此循环下去。

这样一来,就可以充分利用数组中的元素,减少不必要的空间浪费,提高队列结构的空间利用率。

在深入了解循环队列的概念之后,我们开始实现循环队列的基本操作,包括入队、出队、判空、判满等。

通过实现这些基础操作,我们更加熟悉了循环队列的内部结构和操作流程,同时也掌握了程序设计中的一些基本思路和技巧。

在实验过程中,我们还注意到了循环队列一些常见的问题和局限性。

当队列元素数量达到数组大小时,会出现队列满的情况,此时需要进行特殊处理。

由于循环队列是基于数组实现的,所以其大小是固定的,不能动态调整,这也是循环队列的一个缺陷。

在实验结束后,我们对循环队列的性能进行了一些简单分析。

通过测试,我们发现循环队列在入队和出队操作的时间复杂度都是O(1),即不受元素数量的影响,具有较高的效率。

这进一步证明了循环队列是一种高效的数据结构。

本次实验让我们深入了解了循环队列的内部结构和基本操作,也发现了循环队列存在的问题和局限性。

通过这次实验的实践,我们进一步理解了数据结构的重要性,同时也锻炼了自己的程序设计能力和思维能力。

除了实现循环队列的基本操作,我们还对循环队列进行了扩展,添加了一些实用的操作,比如获取队列长度、获取队首和队尾元素等。

这些操作虽然不是必要的,但是在实际的应用中却非常实用,可以方便我们处理队列中的元素。

我们在实验中还掌握了一些编程技巧和调试工具,来提高程序的效率和可靠性。

循环队列基本操作的实现

循环队列基本操作的实现

循环队列基本操作的实现循环队列是一种特殊的队列,它的特点是在连续的存储空间中循环使用。

实现循环队列的基本操作包括初始化队列、入队、出队和判空等。

接下来我将逐个介绍这些操作的实现方法。

1.初始化队列初始化队列的操作包括分配内存空间和设置队头和队尾指针。

在具体实现中,首先需要定义一个循环队列的结构体,包含队列的最大长度、队头指针(front)和队尾指针(rear)以及用于存放元素的数组。

然后使用malloc函数动态分配内存空间,并将队头和队尾指针初始化为0。

2.入队入队操作向队列中添加一个元素。

需要判断队列是否已满,即rear+1等于front,如果是则表示队列已满,不可插入新元素。

否则,将新元素插入到rear指针指向的位置,并更新rear指针。

3.出队出队操作将队头元素删除并返回。

首先需要判断队列是否为空,即front等于rear,如果是则表示队列为空,无法执行出队操作。

否则,将队头指针向后移动一位,并返回删除的元素。

4.判空判空操作用于判断队列是否为空。

当队头指针等于队尾指针时,表示队列为空。

5.判满判满操作用于判断队列是否已满。

当队尾指针的下一位等于队头指针时,表示队列已满。

实现循环队列的基本操作需要考虑边界条件,如何确定队列已满或为空,并且要注意队列的环形特点。

下面给出一个具体的实现示例:```Ctypedef structint* data; // 存放元素的数组int front; // 队头指针int rear; // 队尾指针int maxSize; // 最大长度} CircularQueue;//初始化队列void initQueue(CircularQueue* queue, int maxSize)queue->data = (int*)malloc(maxSize * sizeof(int));queue->front = queue->rear = 0;queue->maxSize = maxSize;//入队操作void enQueue(CircularQueue* queue, int element)if ((queue->rear + 1) % queue->maxSize == queue->front)printf("Queue is full\n");return;}queue->data[queue->rear] = element;queue->rear = (queue->rear + 1) % queue->maxSize; //出队操作int deQueue(CircularQueue* queue)if (queue->front == queue->rear)printf("Queue is empty\n");return -1;}int element = queue->data[queue->front];queue->front = (queue->front + 1) % queue->maxSize; return element;//判空操作int isEmpty(CircularQueue* queue)return queue->front == queue->rear;//判满操作int isFull(CircularQueue* queue)return (queue->rear + 1) % queue->maxSize == queue->front;```以上就是循环队列的基本操作的实现方法。

实现循环队列的入队出队等基本操作

实现循环队列的入队出队等基本操作

实现循环队列的入队出队等基本操作循环队列是一种特殊的队列数据结构,通过循环利用数组空间来实现入队和出队操作。

它的特点是队头和队尾可以在数组上循环移动,从而充分利用数组空间,提高队列的效率。

下面将详细介绍循环队列的实现。

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.判满操作判满操作会检查队尾指针的下一位是否等于队头指针,如果相等则说明队列已满。

数据结构C语言版实验五 循环队列的基本操作

数据结构C语言版实验五 循环队列的基本操作
if((Q.rear+1)% MAXQSIZE ==Q.front) return 0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return 1;
}
int DeQueue(SqQueue &Q,QElemType &e) {
if(Q.front==Q.rear) return 0;
(1)能够熟练在Visual C++6.0环境中进行程序的编辑、编译和调试;
(2)会书写类C语言的算法,并将算法转变为程序实现。
4、程序运行框架
#include <stdio.h>
#include <malloc.h>
#define MAXQSIZE 5
typedef char QElemType;
typedef struct {
QElemType *base;
int front;
int rear;
}SqQueue;
int InitQueue(SqQueue &Q) {return 0; }
int QueueLength(SqQueue Q) {return 0; }
补充程序,在循环队列中依次将元素A、B、C、D入队,求队列长度之后出队,再将E、F入队最后显示队列元素,并观察运行结果。
实验内容可执行程序:
#include <stdio.h>
#include <malloc.h>
#define MAXQSIZE 5
typedef char QElemType;

循环队列的基本运算实现

循环队列的基本运算实现
不同点:
① 运算规则不同,线性表为随机存取,而栈是只允 许在一端进行插入和删除运算,因而是后进先出 表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
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验五循环队列的实现一.实验目的掌握队列的基本操作:初始化队列、判队空、入队、出队等运算及程序实现方法。

二.实验内容(1)定义队列的顺序存取结构—循环队列。

(2)分别定义循环队列的基本操作(初始化队列、判队空、入队、出队等)。

(3)设计一个测试主函数进行测试。

三.实验要求(1)根据实验内容编写程序,上机调试并获得运行结果(2)撰写实验报告四.准备工作本次实验将会建立下图所示循环队列,并会根据此循环队列进行新增,删除等操作五.关键操作思路与算法(1).循环队列的类型定义语句如下;1.typedef struct2.{3.int front,rear;4. datatype data[MAXNUM];5.}SeqQueue;(2)置空队1.//置空队2.SeqQueue * SQueueCreate()3.{4. SeqQueue * sq=(SeqQueue*)malloc(sizeof(SeqQueue));5.if(sq==NULL)6. {7. printf("溢出!\n");8. }9.else10. {11. sq->front=sq->rear=0;12. }13.return sq;14.}(3)入队1.//进队2.void SQueueEnQueue(SeqQueue *sq,datatype x)3.{4.if((sq->rear+1)%MAXNUM==sq->front)5. {6. printf("队列满!\n");7. }8.else9. {10. sq->rear = (sq->rear+1)%MAXNUM;11. sq->data[sq->rear] = x ;12. }13.14.}(4)出队1.//出队2.int SQueueDeQueue(SeqQueue *sq,datatype *e)3.{4.if (sq->front==sq->rear)5. {6. printf("栈空!\n");7.return ERROR;8. }9.else10. {11. sq->front = (sq->front+1)%MAXNUM;12. *e = sq->data[sq->front];13.return OK;14. }15.}(5)判断队空1.//判断空函数2.int SQueueIsEmpty(SeqQueue *sq)3.{4.if (sq->front==sq->rear)5. {6.return TRUE;7. }8.else9. {10.return FALSE;11. }12.}六.源代码1.#include<string.h>2.#include<malloc.h>3.#include<limits.h>4.#include<stdio.h>5.#include<stdlib.h>6.#include<io.h>7.#include<math.h>8.#include<process.h>9.#define TRUE 110.#define FALSE 011.#define OK 112.#define ERROR -113.#define INFEASIBLE -114.#define MAXNUM 10015.typedef int datatype;16.17.typedef struct18.{19.int front,rear;20. datatype data[MAXNUM];21.}SeqQueue;22.//置空队23.SeqQueue * SQueueCreate()24.{25. SeqQueue * sq=(SeqQueue*)malloc(sizeof(SeqQueue));26.if(sq==NULL)27. {28. printf("溢出!\n");29. }30.else31. {32. sq->front=sq->rear=0;33. }34.return sq;35.}36.//判断空函数37.int SQueueIsEmpty(SeqQueue *sq)38.{39.if (sq->front==sq->rear)40. {41.return TRUE;42. }43.else44. {45.return FALSE;46. }47.}48.//进队49.void SQueueEnQueue(SeqQueue *sq,datatype x)50.{51.if((sq->rear+1)%MAXNUM==sq->front)52. {53. printf("队列满!\n");54. }55.else56. {57. sq->rear = (sq->rear+1)%MAXNUM;58. sq->data[sq->rear] = x ;59. }60.61.}62.//出队63.int SQueueDeQueue(SeqQueue *sq,datatype *e)64.{65.if (sq->front==sq->rear)66. {67. printf("栈空!\n");68.return ERROR;69. }70.else71. {72. sq->front = (sq->front+1)%MAXNUM;73. *e = sq->data[sq->front];74.return OK;75. }76.}77.//读对头元素78.datatype SQueueFront (SeqQueue *sq)79.{80.if (sq->front == sq->rear)81. {82. printf("队空下溢\n");83.return ERROR;84. }85.else86. {87.return(sq->data[(sq->front+1)%MAXNUM]);88. }89.}90.//输出循环序列91.void SQueueprint(SeqQueue *sq)92.{93.int i =(sq->front +1)%MAXNUM;94.while (i!=sq->rear+1)95. {96. printf("\t%d",sq->data[i]);97. i = (i+1)%MAXNUM;98. }99.// for(int i = (sq->front + 1)%MAXNUM;i != sq->rear + 1;i = (i + 1) % MAXNUM)100.// printf("\t%d",sq->data[i]);101.}102.103.int main()104.{105. SeqQueue *q;106. datatype x;107.int read;108.do109. {110. puts(" 关于循环队列的操作\n");111. puts(" ===========================\n"); 112. puts(" 1------置空队");113. puts(" 2------入队");114. puts(" 3------出队");115. puts(" 4------判断空队");116. puts(" 5------输出");117. puts(" 6------读队头元素");118. puts(" 0------退出");119. printf(" 请选择代号(0-6):");120. scanf("%d",&read);121. printf("\n");122.switch(read)123. {124.case 1:125. q=SQueueCreate();126.break;127.case 2:128. printf("请输入需要入队的元素:");129. scanf("%d",&x);130. SQueueEnQueue(q,x);131.break;132.case 3:133. SQueueDeQueue(q,&x);134. printf("出队数据元素是: %d\n",x);135.break;136.case 4:137.if (SQueueIsEmpty(q))138. {139. printf("队列已空!\n");140. }141.else142. {143. printf("队列不空!\n");144. }145.break;146.case 5:147. printf("\n 现在队列中的元素依次为:\n");148. SQueueprint(q);149. printf("\n");150.break;151.case 6:152. x = SQueueFront(q);153. printf("%d",x);154.break;155.case 0:156. read = 0;157.break;158.default:;159. }160. }while(read != 0);161.}七.程序图七.实验总结本届实验学习了队列这种操作受限的线性表,它只允许在一端插入,并在另一端进行删除在表中只允许进行插入的那一端称为队尾,只允许进行删除的那一段称为队头队头元素总是最先进队列的,同时也是最后出队列的,而对尾元素最后进队列的,同时也是最先出队列的,因此,队列也被称为”先进先出”的线性表,队列采用顺序存储结构时,为了解决假溢出问题,常常会设计成循环链表(首尾相连)来存储。

相关文档
最新文档