实习04_循环队列

合集下载

循环队列的基本操作

循环队列的基本操作

实验四循环队列的基本操作实验目的:1、熟悉将算法转换成程序代码的过程。

2、了解单循环队列的逻辑结构特性,熟练掌握循环队列顺序存储结构的C 语言描述方法。

3、熟练掌握循环队列的基本操作:入队、出队等,掌握循环队列的存取特性。

实验内容:1、分别建立包含6个数据元素的循环队列;2、从键盘输入一个数据元素x,进行入队操作;3、获取队头元素的值;4、对循环队列进行出队操作;5、打印循环队列元素和队列长度;6、给出程序及各项操作结果。

实验步骤:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define MAXSIZE 100 /*队列的最大容量*/typedef int DataType;typedef struct {DataType data[MAXSIZE]; /*队列的存储空间*/int front, rear; /*队头队尾指针*/}SeqQueue,*PSeqQueue;PSeqQueue Init_SeqQueue( ){ /*初始化一新队列,入口参数:无,返回值:新顺序队列指针,null表示失败*/ PSeqQueue Q;Q=( PSeqQueue )malloc(sizeof(SeqQueue));if (Q){Q->front=0;Q->rear=0;printf("置空队列成功!");}return Q;}void Destroy_SeqQueue(PSeqQueue *Q){ /*销毁一队列,入口参数:要销毁的顺序队列指针的地址,返回值:无*/ if (*Q)free(*Q);*Q=NULL;}int Empty_SeqQueue(PSeqQueue Q)/*判断队列是否为空,入口参数:顺序队列,返回值:1表示为空,0表示非空*/{ if (Q && Q->front==Q->rear)return (1);elsereturn (0);}int QueueLength (PSeqQueue Q){学生自己写}//返回Q的元素个数,即队列的长度int In_SeqQueue ( PSeqQueue Q , DataType x)/*入队操作,入口参数:顺序队列和待入队元素x ,返回值:1表示成功,-1表示队满溢出*/{ if ((Q->rear+1)%MAXSIZE==Q->front){ printf("队满");return -1; /*队满不能入队*/}else{ Q->rear=(Q->rear+1) % MAXSIZE;Q->data[Q->rear]=x;return 1; /*入队完成*/}}int Out_SeqQueue (PSeqQueue Q,DataType *x){ /*出队操作,入口参数:顺序队列,返回值:1表示成功,-1表示队空,出队的元素保存到*x */if (Empty_SeqQueue(Q)){printf("队空");return -1; /*队空不能出队*/}else{ Q->front=(Q->front+1) % MAXSIZE;*x=Q->data[Q->front];return 1; /*出队完成*/}}int Front_SeqQueue(PSeqQueue Q ,DataType *x){ /*取队头元素,入口参数:顺序队列和取出元素存放地址,返回值:1表示成功,-1表示队空*/if (Q->front==Q->rear){printf("队空");return -1; /*队空不能得到队头元素*/}else{ *x=Q->data[(Q->front+1)%MAXSIZE];return 1; /*取队头元素操作完成*/}}void display(PSeqQueue S){学生填写}void main(){(由学生填写)}实验用测试数据和相关结果分析:(由学生填写)实验总结:(由学生填写)。

顺序队列(循环队列)

顺序队列(循环队列)

顺序队列(循环队列)概述队列(queue)是⼀种只允许在⼀端进⾏插⼊操作,⽽在另⼀端进⾏删除操作的线性表。

队列是⼀种先进先出(First In First Out)的线性表,简称FIFO。

允许插⼊的⼀端称为队尾,允许删除的⼀端称为队头。

因为已经限制了插⼊和删除的位置,所以对于队列,插⼊和删除时只需要考虑满和空两种状态。

线性表存储结构分为顺序存储和链式存储,这⾥只讨论静态分配的顺序存储结构。

约定为了⽅便起见,我们约定:1、初始化建队列时,令队头指针m_nFront和队尾指针m_nRear等于0,即m_nFront = m_nRear = 0;2、m_nFront指向队头元素的位置,m_nRear指向队尾元素的下⼀位。

关键点1、顺序队列的假上溢现象顺序队列的操作分别在队头和队尾两端进⾏。

在出队时,队头m_nFront和队尾m_nRear的值都是只增加(向队列长度m_nCount)靠近;如果仅通过m_nRear == m_nCount来判断顺序队列是否满队,此时可能存在m_nRear已经指向m_nCount,同时m_nFront > 0(已有元素出队),顺序队列中实际的元素个数远⼩于m_nCount⽽不能做⼊队操作的情况,导致元素出队后的空闲存储空间永远⽆法重⽤,造成假上溢。

如下图:解决⽅法:为克服假上溢,可将顺序队列想象为⼀个⾸尾相接的环状空间,称为循环队列。

在循环队列中出队⼊队时,头尾指针仍向前移动进⾏加1操作,当头尾指针指向m_nCount时,头尾指针加1操作的结果重新指向下界0(加1后对m_nCount做取余数运算)。

2、判断队空和队满想象成循环队列后,当⼊队时,m_nRear向前追赶m_nFront,出队时,m_nFront向前追赶m_nRear,故存在队空和队满时都有m_nFront ==m_nRear的情况,因此⽆法通过m_nFront == m_nRear来判断队空还是队满。

解决⽅法:牺牲存储空间中的⼀个存储单元,使队空和队满的判断条件不同即可,具体的:1)出队时,m_nRear == m_nFront时,表⽰队空,此时不能出队。

数据结构上机4_循环队列

数据结构上机4_循环队列

实验四队列(循环队列的创建、添加和删除操作)
1.实验目的:掌握循环队列的基本操作,并对其进行简单应用。

2.实验内容:
假设循环队列的最大长度为7,现在依次将以下数据入队列:{7,5,3,9,2,4};
接着进行3次出队列的操作,再将15、18这两个数据入队列,最后从对头到队尾依次输出队列中的元素。

3.实验步骤:
源代码:
运行结果;
4.总结
在C语言中不能用动态分配的一维数组来实现循环队列。

如果用户的应用程序中设有循环队列,则必须为他设定一个最大队列长度;若用户无法预估队列的最大长度,则宜采用链队列。

循环队列存储结构的c语言描述

循环队列存储结构的c语言描述

循环队列存储结构的c语言描述1.引言1.1 概述在这一部分中,我们将概述循环队列的存储结构和其在C语言中的描述。

循环队列是一种特殊的队列,它通过数组来实现元素的存储和访问。

与普通队列不同的是,循环队列允许在队列头尾进行操作,即当队列满时,新的元素可以覆盖队列头部的元素。

循环队列的存储结构可以用一个数组来表示,其中使用两个指针分别指向队列的头部和尾部。

初始时,这两个指针指向同一个位置,表示队列为空。

当有元素入队时,尾指针向后移动并存储新的元素;当有元素出队时,头指针向后移动并删除队列头部的元素。

循环队列的实现方法有很多种,我们将在后面的部分逐一介绍。

总的来说,循环队列在存储和访问元素时具有高效性和灵活性的优点。

然而,它也有一些缺点,比如需要事先确定队列的最大容量,且存储空间可能会浪费一部分。

在本文的后续部分,我们将详细介绍循环队列的定义和特点,包括队列空和队列满的条件;同时,我们还将介绍一些常用的实现方法,包括使用固定长度的数组以及动态分配内存空间的方式。

最后,我们将给出C语言描述循环队列的代码示例,以帮助读者更好地理解和实践该数据结构。

通过掌握循环队列的基本概念和相应的C语言实现,读者将能够应用循环队列解决实际问题,并在程序设计中发挥其优势。

接下来,让我们进入正文部分,详细了解循环队列的定义和特点。

文章结构部分的内容可以按照以下方式来编写:1.2 文章结构本文将按照如下结构进行叙述循环队列存储结构的C语言描述:1. 引言:首先介绍循环队列这种数据结构的背景和作用,以及本文将要讨论的问题。

2. 正文:主要呈现循环队列的定义和特点,以及不同的实现方法。

在循环队列的定义和特点部分,将介绍什么是循环队列以及其与一般队列的区别。

在循环队列的实现方法部分,将讨论如何用C语言来实现循环队列,包括如何定义循环队列的结构体和相关操作函数的实现。

3. 结论:对循环队列的优缺点进行总结,以及给出用C语言描述循环队列的代码示例。

循环队列及链队列的基本操作 头歌

循环队列及链队列的基本操作 头歌

循环队列及链队列的基本操作1. 循环队列的基本概念和原理循环队列是一种常见的数据结构,它具有队列的特点,即先进先出(FIFO)。

与普通队列相比,循环队列的特点在于它可以充分利用数组的空间,解决了普通队列在出队操作时需要频繁搬移数据的问题。

循环队列的基本原理是使用环形数组来实现队列的存储和操作,通过头指针和尾指针的移动,实现队列的入队和出队操作。

2. 循环队列的基本操作2.1 入队操作:将元素插入队列的尾部,并更新尾指针的位置。

2.2 出队操作:从队列的头部取出元素,并更新头指针的位置。

2.3 判空操作:当头指针和尾指针重合时,队列为空。

2.4 判满操作:当尾指针的下一个位置与头指针重合时,队列为满。

3. 链队列的基本概念和原理链队列是另一种常见的队列实现方式,与循环队列不同的是,链队列使用链表来存储队列元素。

链队列的基本原理是使用链表的头节点和尾节点来实现队列的操作,通过指针的移动,实现入队和出队操作。

4. 链队列的基本操作4.1 入队操作:将元素插入队列的尾部,并更新尾节点的位置。

4.2 出队操作:从队列的头部取出元素,并更新头节点的位置。

4.3 判空操作:当头节点和尾节点指向同一个节点时,队列为空。

4.4 遍历操作:通过指针的遍历,可以获取队列中的所有元素。

5. 总结和回顾通过对循环队列和链队列的基本概念、原理和操作进行分析,我们可以看出它们都是用于实现队列功能的数据结构,但在不同的场景下有着不同的优势和应用。

循环队列适合于对空间有限且需要频繁进行入队和出队操作的场景,而链队列适合于对空间要求宽松、对操作有一定顺序要求的场景。

6. 个人观点和理解在实际编程中,循环队列和链队列都有着各自的优点和局限性,需要根据具体的场景和需求来选择合适的队列实现方式。

在使用循环队列时,需要注意头尾指针的移动,避免产生死循环和队列溢出的问题;而在使用链队列时,需要考虑对节点的动态分配和释放,避免产生内存泄漏和指针错乱的问题。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

数据结构实验4循环队列的实现和运算

数据结构实验4循环队列的实现和运算

数据结构实验4循环队列的实现和运算循环队列是一种特殊的队列,它的特点是可以循环利用已经出队的元
素所占用的空间。

循环队列采用一维数组来实现,通常需要两个指针(称
为队头指针front和队尾指针rear)。

循环队列的基本操作包括初始化、判空、判满、入队、出队、获取队
头元素等。

1. 初始化:循环队列的初始化很简单,只需将队头指针front和队
尾指针rear都置为0即可。

2. 判空:当队头指针front和队尾指针rear相等时,队列为空。

3. 判满:当队尾指针rear加1后等于队头指针front时,队列为满。

4. 入队操作:在插入元素之前,需要判断队列是否已满。

如果队列
为满,则无法插入新的元素;否则,在rear指针的位置插入新的元素,
并将rear指针往后移动一位。

5. 出队操作:在删除元素之前,需要判断队列是否为空。

如果队列
为空,则无法删除元素;否则,在front指针的位置删除元素,并将
front指针往后移动一位。

6. 获取队头元素:获取队列的队头元素很简单,只需返回front指
针位置的元素即可。

循环队列的实现比较简洁高效,主要是通过取模运算来实现队列指针
的循环移动。

当rear指针到达数组的最后一个位置时,再插入新的元素时,需要将rear指针指向数组的第一个位置;当front指针在数组的最
后一个位置上时,再删除元素时,需要将front指针指向数组的第一个位置。

通过循环队列的实现和运算,可以高效地进行队列的操作,从而提高算法的执行效率。

在实际应用中,循环队列常被用于实现缓冲区、进程调度等场景。

循环队列

循环队列

循环队列
5 4 0
Q.front
Q.rear
3 2
1
2 Q.front
队列“满”
Q.rear
队列“空”
Q.front=Q.rear?????
队列的顺序存储
区分队列是“空”还是“满”;
循环队列
5 4
J6 J5 J7 0
解决方法:一是为队列另设一个标志,用来 二是少用一个元素空间,当队列头指针在队 列尾指针的下一个单元时就认为队“满”。 此时,队尾指针只差一步追上队头指针。即:
队列的顺序存储
(4)获取队头元素内容
循环队列
int GetFront (SqQueue Q, QElemType *e) { if (QueueEmpty (Q)) return EMPTY; else e=Q.base[Q.front]; return OK; } (5)判断队列Q是否为空 int QueueEmpty (SqQueue *Q) { if (Q->front==Q->rear) return TRUE; else return FALSE; }
(Q.rear+1)%MAXQSIZE==Q.front。
一般用第二种方法。
J4
3 J3 2 Q.front 1 Q.rear
判空条件:Q.rear=Q.front 判满条件: (Q.rear+1)%MAXQSIZE=Q.front
队列的顺序存储
循环队列
#define MAXQSIZE 100 //队列的最大数据元素数目 typedef struct queue {//假设只剩下一个单元时认为队满 QElemType *base;//初始化分配的存储空间 int front; //队头指针 int rear; //队尾指针 }SqQueue; (1)初始化队列Q int InitQueue (SqQueue &Q) { Q.base=(QElemType*)malloc(MAXQSIZE* sizeof(QElemType)); if(!Q.base) exit(OVERFLOW); Q.front=Q.rear=0; return OK; }

队列(循环队列)的表示和实现

队列(循环队列)的表示和实现

浙江大学城市学院实验报告课程名称数据结构基础实验项目名称实验八队列(循环队列)的表示和实现学生姓名专业班级学号实验成绩指导老师(签名)日期04 28一.实验目的和要求1、掌握队列的存储结构及基本操作。

2、掌握循环队列的设置及循环队列的各种基本操作的实现。

3、通过具体的应用实例,进一步熟悉和掌握队列的实际应用。

二.实验内容1、建立头文件test8.h,定义顺序存储的循环队列存储结构,并编写循环队列的各种基本操作实现函数。

同时建立一个验证操作实现的主函数文件test8.cpp,编译并调试程序,直到正确运行。

说明:队列的基本操作可包括:①void InitQueue (Queue &Q); //构造一个空队列Q②int EmptyQueue (Queue Q);//判断队列Q是否为空,若空返回1,否则返回0③void EnQueue (Queue &Q, ElemType item); //元素item 进队列Q④ElemType OutQueue (Queue &Q); //队头元素出队列Q,并返回其值⑤ElemType PeekQueue (Queue Q); //返回队头元素值⑥void ClearQueue (Queue &Q); //清空队列2、应用(选做部分):编写程序,实现舞伴问题:假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队,跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴,若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。

现要求设计一个函数void partner(),模拟上述舞伴配对问题。

基本要求:1)由键盘输入数据,每对数据包括姓名和性别;2)输出结果包括配成舞伴的女士和男士的姓名,以及未配对者的队伍名称和队头者的姓名;3)要求利用test8.h中已实现的顺序循环队列的基本操作函数来实现。

函数void partner()添加到文件test8.cpp中,在主函数中进行调用测试。

循环队列的概念

循环队列的概念

循环队列的概念
循环队列是一种特殊的队列数据结构,它具有固定大小的缓冲区,可以在其中存储元素,并支持在队列前端和后端插入和删除元素。

与普通队列不同的是,循环队列允许在缓冲区的末尾和开头之间进行循环操作,从而实现更高效的内存利用。

循环队列的实现方法通常使用一个数组来表示缓冲区,并使用两个指针来指示队列的头部和尾部。

当一个元素被添加到队列中时,尾指针会向前移动一位,并将该元素存储到数组中相应的位置上。

当一个元素从队列中被删除时,头指针会向前移动一位,并从数组中相应位置上取出该元素。

由于循环队列具有固定大小的缓冲区,因此在插入新元素时可能会出现“溢出”的情况。

为了避免这种情况发生,循环队列需要使用一些技巧来判断当前是否还有空间可以存储新元素。

例如,在插入新元素时可以检查头指针和尾指针之间是否还有空闲位置,如果没有则说明缓冲区已满。

另外,在实际应用中通常需要考虑多线程环境下的并发操作问题。

为了保证多线程操作的正确性,循环队列需要使用一些同步机制来避免竞争条件的发生。

例如,在插入和删除元素时可以使用互斥锁或读写
锁来保证同一时刻只有一个线程可以访问队列。

总之,循环队列是一种非常常用的数据结构,它可以在内存中高效地存储和管理元素,并支持快速插入和删除操作。

在实际应用中,循环队列通常被用于缓存数据、消息传递、任务调度等场景中。

循环队列详解及队列的顺序表示和实现

循环队列详解及队列的顺序表示和实现

循环队列详解及队列的顺序表⽰和实现循环队列——队列的顺序表⽰和实现前⾯分析顺序队的时候,我们知道,顺序队存在”假溢出”的问题,这个问题有时会造成很⼤的内存浪费,循环队列就是为了解决这个问题⽽提出地⼀个很巧妙的办法.循环队列和顺序队列的主要区别在于:循环队列将顺序队列臆造成⼀个环状空间.在操作上这种异同体现在:相同点:在顺序队列和循环队列中,进⾏出队、⼊队操作时,队⾸、队尾指针都要加 1 ,朝前移动。

不同点:1. 在循环队列中当队⾸、队尾指针指向向量上界(MAX_QUEUE_SIZE-1) 时,其加1 操作的结果是指向向量的下界 0 。

⽽在顺序队列中,说明队已满,若此时采⽤的是动态顺序链,可以增加申请内存.若是采⽤静态顺序链,只能退出程序.2. 顺序队列中q.front = q.rear 表⽰队空,q.rear = MAX_QUEUE_SIZE表⽰队满.⽽在循环队列中.front=q.rear表⽰队空,⽽⽆法⽤.rear=MAX_QUEUE_SIZE表⽰队满.判断循环队列队满的两种⽅法(本⽂采⽤第⼆种⽅法):1.另设⼀个标志位以区分队列是空还是满2.少⽤⼀个元素空间,约定以”队列头指针在队列尾指针的下⼀位置上”,作为队列呈满状态的标志.第⼆种⽅法的实现:◆ rear 所指的单元始终为空。

◆循环队列为空: front=rear 。

◆循环队列满: (rear+1)%MAX_QUEUE_SIZE=front 。

循环队列操作及指针变化情况如下图所⽰:循环队列虽然可以解决”假溢出”问题,但是它不能通过动态分配的⼀维数组来实现,所以在实现循环队列之前,⼀定要为它设定⼀个最⼤队列长度.如果⽆法预估所需的最⼤队列长度,只能采⽤来链表实现.代码实现:循环队列和顺序队列的头⽂件是⼀样的/* 循环队列的接⼝定义头⽂件 */#define true 1#define false 0/* 队的最⼤长度 */#define MAX_QUEUE_SIZE 6/* 队列的数据类型 */typedef int datatype;/* 静态链的数据结构 */typedef struct queue{datatype sp_queue_array[MAX_QUEUE_SIZE];/* 队头 */int front;/* 队尾 */int rear;}cir_queue;/* 静态顺序链的接⼝定义 *//* 静态链的初始化 */cir_queue queue_init();/* 判断队列是否为空,若为空* 返回true* 否则返回false*/int queue_empty(cir_queue q);/* 插⼊元素e为队q的队尾新元素* 插⼊成功返回true* 队满返回false*/int queue_en(cir_queue *q, datatype e);/* 队头元素出队* ⽤e返回出队元素,并返回true* 若队空返回false*/int queue_de(cir_queue *q, datatype *e);/* 清空队 */void queue_clear(cir_queue *q);/* 获得队头元素* 队列⾮空,⽤e返回队头元素,并返回true* 否则返回false*/int get_front(cir_queue, datatype *e );/* 获得队长 */int queue_len(cir_queue q);/* 遍历队 */void queue_traverse(cir_queue q, void(*visit)(cir_queue q)); void visit(cir_queue s);/* 循环队列的接⼝实现⽂件 */#include<stdio.h>#include<stdlib.h>#include"cir_queue.h"cir_queue queue_init(){cir_queue q;q.front = q. rear = 0;return q;}int queue_empty(cir_queue q){return q.front == q.rear;}int queue_en(cir_queue *q, datatype e){/* 判断队是否已满 */if (q -> front == (q -> rear + 1) % MAX_QUEUE_SIZE) return false;/* ⼊队 */q -> sp_queue_array[q -> rear] = e;q -> rear = (q -> rear + 1) % MAX_QUEUE_SIZE;return true;}int queue_de(cir_queue *q, datatype *e){/* 判断队列是否为空 */if(q -> front == q -> rear)return false;/* ⽤e返回队头元素 */*e = q -> sp_queue_array[q -> front];q -> front = (q -> front + 1 ) % MAX_QUEUE_SIZE;return true;}void queue_clear(cir_queue *q){q -> front = q -> rear = 0;}int get_front(cir_queue q, datatype *e){/* 判断队列是否为空 */if (q.front == q.rear)return false;*e = q.sp_queue_array[q.front];return true;}int queue_len(cir_queue q){/* 若front > rear */if(q.front > q.rear)return (q.rear + MAX_QUEUE_SIZE - q.front);elsereturn (q.rear - q.front);}void queue_traverse(cir_queue q, void(*visit)(cir_queue q)) {visit(q);}void visit(cir_queue q){while(q.front != q.rear){printf("%d ",q.sp_queue_array[q.front]);q.front = (q.front + 1) % MAX_QUEUE_SIZE;}}int main(){cir_queue q = queue_init();queue_en(&q, 1);queue_en(&q, 2);queue_en(&q, 3);queue_en(&q, 4);queue_en(&q, 5);printf("此时队长:length=%d\n", queue_len(q));queue_traverse(q, visit);printf("元素6再⼊队\n");queue_en(&q, 6);queue_traverse(q, visit);datatype *x = (datatype *)malloc(sizeof(*x));queue_de(&q,x);printf("出队:%d,此时队长=%d\n", *x, queue_len(q));printf("元素6再⼊队\n");queue_en(&q, 6);printf("length=%d\n", queue_len(q));queue_traverse(q,visit);datatype *e = (datatype *)malloc(sizeof(*e));queue_de(&q,e);printf("queue_de(),e=%d length=%d\n", *e, queue_len(q)); queue_traverse(q, visit);queue_clear(&q);queue_traverse(q, visit);printf("length:%d\n", queue_len(q));}运⾏截图:感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。

循环队列

循环队列
功能:取队头元素,用e取得队头元素的值,操作成功返回1.不成功返回0。
4.实验程序清单
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef int elemtype;
#define M 100
}
q->base[q->rear]=e;
q->rear=(q->rear+1)%M;
return OK;
}
int DeQueue(SeqQueue *q,elemtype *e)
{
if(q->front==q->rear)
{
printf("该队列已空.\n");
return ERROR;
}
*e=q->base[q->front];
●调用函数DeQueue(q,&e)让先入队的元素出队。
●调用函数GetHead(q,&e)弹出队头的元素。
●调用函数QueueEmpty(q)判断对列是否为空。
●调用函数ClearQueue(q)清空队列的内容。
●调用函数QueueLength(q)求队列的深度。
7.试验心得及收获
心得:(1)通过本次实验,理解栈的概念
break;
default:
printf("请选择菜单中的操作,按0退出程序\n");
}
}
}
5.实验程序执行结果
6.执行结果的分析:
●调用void showmenu()显示选择菜单,在main()函数中使用case语句实现菜单项的选择。

循环队列的基本操作

循环队列的基本操作

循环队列的基本操作循环队列(Circular Queue)是一种用数组实现的队列数据结构,具有固定大小并按照循环方式使用空间的特点。

循环队列有着基本的操作:入队、出队、判空、判满、获取队头元素、获取队列长度。

1. 入队(Enqueue)操作:入队操作是将元素添加到队列的末尾。

当队列为空时,设置队头和队尾均为0;当队列不满时,将元素插入到队尾,并将队尾指针向后移动一位;当队列满时,不再插入新元素。

算法步骤:1.如果队列已满,返回错误或抛出异常。

2.将元素放入队尾位置。

3.队尾指针向后移动一位(考虑取模操作,以实现循环)。

4.返回成功入队的标志。

2. 出队(Dequeue)操作:出队操作是将队头元素移除,并返回该元素。

当队列为空时,无法进行出队操作。

算法步骤:1.如果队列为空,返回错误或抛出异常。

2.记录队头元素的值。

3.队头指针向后移动一位(考虑取模操作,以实现循环)。

4.返回记录的队头元素值。

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

当队头和队尾指针相等且队列中无元素时,队列为空。

算法步骤:1.如果队头和队尾指针相等,返回队列为空的标志。

2.否则,返回队列不为空的标志。

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

当队头和队尾指针相等且队列中有元素时,队列已满。

算法步骤:1.如果队头和队尾指针相等且队列中有元素,返回队列已满的标志。

2.否则,返回队列未满的标志。

5. 获取队头元素(Get Front):获取队头元素操作用于返回队列中的队头元素,但不移除该元素。

当队列为空时,无法获取队头元素。

算法步骤:1.如果队列为空,返回错误或抛出异常。

2.返回队头指针位置元素的值。

6. 获取队列长度(Get Size):获取队列长度操作用于返回队列中元素的个数。

队列的长度等于队尾指针减去队头指针。

算法步骤:1.返回队尾指针减去队头指针的绝对值。

循环队列的基本操作就是以上六个,它们用于实现循环队列的基本功能。

循环队列的优点是可以更好地利用空间,而不会造成空间浪费。

循环队列

循环队列

南京信息工程大学循环队列实验(实习)报告实验(实习)名称循环队列实验(实习)日期得分指导老师系理学系专业实验班班级 2 姓名孙浩宇学号201423210371、需求分析要求:编写一个头文件SqQueue.h,实现顺序循环队列的各种运算,并在此基础上设计一个主程序完成如下功能:(1)初始化队列q(1)判断队列q是否非空(2)依次进队列元素a,b,c(3)出队一个元素,输出该元素(4)输出队列q的元素个数(5)依次进队列元素d,e,f(6)输出队列q的元素个数(7)输出出队序列(8)释放队列2、设计#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define NULL 0typedef int Status;typedef char QElemType;typedef struct QNode{QElemType data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;Status InitQueue(LinkQueue &Q){Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front)exit(OVERFLOW);Q.front->next=NULL;return OK;}Status EnQueue(LinkQueue &Q,QElemType e){QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e; p->next=NULL;Q.rear->next=p;Q.rear=p;return OK;}Status OutQueue(LinkQueue &Q){QueuePtr p;if(Q.front==Q.rear) return ERROR; //空队列,返回error p=Q.front->next; //p指向队首元素Q.front->next =p->next;printf("%c\n",p->data);if(Q.rear == p) Q.rear =Q.front ; //如果p是最后一个元素free (p);return OK;}Status DestroyQueue(LinkQueue &Q){while(Q.front){Q.rear=Q.front->next;free(Q.front);Q.front=Q.rear;}return OK;}int QueueLength(LinkQueue &Q){QueuePtr p;int i=0;for(p=Q.front->next ;p!=NULL;p=p->next)i++;return i;}Status QueueTraverse(LinkQueue &Q){QueuePtr p;for(p=Q.front->next ;p!=NULL;p=p->next){printf("%c",p->data);}return OK;}/*文件名:exp3-2.cpp*/#include<stdio.h>#include"SqQueue.h"void main(){LinkQueue Q;printf("(1)初始化队列q\n");InitQueue(Q);printf("队列长度:%d\n",QueueLength(Q));printf("(2)依次进入对列a,b,c元素\n");EnQueue(Q,'a');EnQueue(Q,'b');EnQueue(Q,'c');printf("(3)队列Q元素个数=%d\n",QueueLength(Q));printf("(4)出队:");OutQueue(Q);printf("(5)队列Q元素个数=%d\n",QueueLength(Q));printf("(6)依次进入对列d,e,f元素\n");EnQueue(Q,'d');EnQueue(Q,'e');EnQueue(Q,'f');printf("(7)队列Q元素个数=%d\n",QueueLength(Q));printf("(8)输出队列");QueueTraverse(Q);printf("(9)释放对列\n");DestroyQueue(Q);}3、调试分析还是对指针运用不熟悉,经常在指针的指向问题上出错,导致程序不能运行,出现error。

实验四循环队列基本操作及相关算法的实现

实验四循环队列基本操作及相关算法的实现

实验四循环队列基本操作及相关算法的实现一、实验目的:掌握循环队列的基本操作及在顺序存储结构上的实现。

二、实验环境:Visual C++6.0三、实验要求:(1)实现队列的顺序存储及基本操作(2)实现两个队列的拼接四、实验步骤:(1)数据结构的定义及实现用结构类型来定义队列的类型#define MaxSize 100 //最大元素个数#define ElemType char#define MaxNumber 100typedef struct //顺序循环队列的类型定义{ ElemType data[MaxSize]; //队列元素存储空间int front; //对头指针int rear; //队尾指针}*CircSeqQueue;#define Apply(pQ) pQ=(CircSeqQueue)malloc(sizeof(CircSeqQueue));(2) 基本操作定义及实现void QueueInitial(CircSeqQueue pQ); //顺序循环队列的初始化int IsEmpty(CircSeqQueue pQ); //顺序循环队列判空int IsFull(CircSeqQueue pQ); //顺序循环队列判满void EnQueue(CircSeqQueue pQ,ElemType e); //元素进队ElemType DeQueue(CircSeqQueue pQ); //元素出队ElemType GetFront(CircSeqQueue pQ); //取队头元素值void display(CircSeqQueue pQ); //遍历队列,并显示void MakeEmpty(CircSeqQueue pQ); //循环队置空void Union(CircSeqQueue pQ1,CircSeqQueue pQ2);//将队列pQ2所指的队列中的元素加到pQ1所指的队列的队尾现具体说顺序栈的元素进队和遍历队列的实现方法,其他的基本操作请参看Queue.cpp 和具体的源程序元素进队:void EnQueue(CircSeqQueue pQ,ElemType e){ //若队列不满,则元素e进队if (IsFull(pQ)) //队列已满,退出{printf("队列溢出!");exit(1);}pQ->rear=(pQ->rear+1)%MaxSize; //队尾指针后移pQ->data[pQ->rear]=e;}void display(CircSeqQueue pQ){if (IsEmpty(pQ)) //如果队列为空,显示空队列{printf("空队列!\n");}while (!IsEmpty(pQ)) //如果不为空,打印队头元素{printf("%-5c",pQ->data[(pQ->front+1)%MaxSize]);pQ->front=(pQ->front+1)%MaxSize; //队头指针向前移一}putchar('\n');}(3) 实现两个队列的拼接,将队列pQ2所指的队列中的元素加到pQ1所指的队列的队尾void Union(CircSeqQueue pQ1,CircSeqQueue pQ2){while (!IsEmpty(pQ2)){EnQueue(pQ1,pQ2->data[(pQ2->front+1)%MaxSize]);//将Q2的队头元素放到Q1尾pQ2->front=(pQ2->front+1)%MaxSize; //Q2的队头指针向下移一位}}(4)主程序流程CircSeqQueue pQ,pQ1,pQ2;Apply(pQ);char d[]={'a','b','c','d','e','f','g','h'};QueueInitial(pQ);for(int i=0;i<=7;i++) EnQueue(pQ,d[i]);printf("\n初始队列元素为:");display(pQ);for(int j=0;j<=7;j++) EnQueue(pQ,d[j]);printf("出队元素为:%c\n",DeQueue(pQ));printf("获取此时的队头元素为:%c\n",GetFront(pQ));printf("将元素m进队后为:");EnQueue(pQ,'m');display(pQ);MakeEmpty(pQ)char d1[]={'x','f','b','m','e'},d2[]="jhxdny";for(int m=0;m<5;m++) EnQueue(pQ1,d1[m]);for(int t=0;t<6;t++) EnQueue(pQ2,d2[t]);Union(pQ1,pQ2);display(pQ1);(5)数据测试及结果分析:经测试结果完全正确,具体结果可以看下面:五总结:由于使用Visual C++来编写程序和对C/C++的语法不够熟悉,所以在调试程序的过程中出现了一些问题。

c语言 文件形式的循环队列

c语言 文件形式的循环队列

c语言文件形式的循环队列一、循环队列的概念和特点循环队列是一种特殊的队列,其特点是队列的尾部和头部是连接在一起的,形成一个循环。

这种设计可以充分利用已经使用过但已经出队的空间,提高队列的空间利用率。

循环队列有两个指针,一个是队头指针front,指向队头元素;一个是队尾指针rear,指向队尾元素的下一个位置。

当队列为空时,front和rear指向同一位置;当队列满时,rear指向队尾元素的下一个位置,而front则指向队头元素。

循环队列的长度可以通过front和rear的位置关系计算得出。

循环队列的主要操作包括入队和出队操作。

入队操作将元素插入队列的队尾,并更新rear指针的位置;出队操作将队头元素删除,并更新front指针的位置。

由于循环队列的特殊设计,入队和出队操作都可以在O(1)的时间复杂度内完成。

二、循环队列的实现原理循环队列可以使用数组来实现。

通过定义一个固定大小的数组,然后使用front和rear指针来指示队列的头部和尾部,可以实现循环队列的基本操作。

具体实现时,需要注意以下几点:1. 初始化队列时,将front和rear指针都指向数组的第一个位置。

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

如果rear指针超出数组范围,则将其重新指向数组的第一个位置。

3. 出队操作时,先将front指针指向的元素删除,然后将front指针向后移动一位。

如果front指针超出数组范围,则将其重新指向数组的第一个位置。

4. 判断队列是否为空时,可以通过front和rear指针是否相等来判断。

5. 判断队列是否已满时,可以通过rear指针的下一个位置是否等于front指针来判断。

三、C语言文件形式的循环队列的实现在C语言中,可以使用文件操作来实现循环队列的读写操作。

通过将队列中的元素写入文件,并从文件中读取元素进行出队操作,可以实现对循环队列的持久化存储。

具体实现时,可以使用文件指针来进行文件的打开和关闭操作,使用fwrite函数将元素写入文件,使用fread函数从文件中读取元素。

循环队列的实现及细节

循环队列的实现及细节

循环队列的实现及细节1. 队列定义:⼀种可以实现 “先进先出” 的存储结构(类似于排队)只允许在⼀端插⼊元素,在另⼀端删除元素,不可以混在⼀起2. 队列分类:链式队列:由链表实现的队列,本质是链表静态队列:由数组实现的队列,本质是数组3. 循环队列讲解1. 静态队列为什么必须时循环队列:静态队列必须是循环队列,这是由数组的特性决定的。

队列只允许尾部添加元素头部删除元素,如果⽤数组实现,添加元素时元素向后排列,删除元素时前⾯的位置就会空出来,时间长了之后会造成⼤量的空间浪费,所以要使⽤循环队列,以防⽌空间浪费⾮循环队列,会浪费很多空间循环队列,不会浪费空间2. 循环队列需要⼏个参数来确定:两个,即队列头、尾(实质上就是数组的两个下标)3. 循环队列各个参数的含义:循环队列需要两个参数来确定,且这两个参数在不同的情况下由不同的含义队列初始化时:front和rear值都为零队列⾮空时:front代表队列第⼀个元素,rear代表队列的最后⼀个有效元素的下⼀个元素队列空时:front和rear相等单不⼀定为零4. 循环队列⼊队伪算法讲解:将值存⼊下标为rear的位置后,rear = (rear+1) %数组长度,⽽不是 rear+15. 循环队列出队伪算法讲解:front = (front + 1) % 数组长度,与⼊队相同6. 如何判断循环队列是否为空:若 rear == front 则队列为空7. 如何判断循环队列是否为满:若(rear + 1)% 数组长度 == front 则队列已满(因为 rear 指⽰的是队列最后⼀个有效元素的下⼀个元素,所以这样判断队列已满会浪费⼀个数组位置,但是这已经⽐⾮循环队列省了很多空间了。

如果要不浪费哪⼀个元素就需要多加⼀个参数,这样就会⿇烦很多,没有必要)4. 循环队列实现及细节#include <stdbool.h>#include <stdio.h>#include <stdlib.h>typedef struct Queue{int *pBase; //指向数组的指针int front; //队列头,数值尾队列第⼀个有效元素的下标int rear; //队列尾,数值尾队列最后⼀个有效元素的下⼀个元素的下标}QUEUE,*PQUEUE;PQUEUE InitQueue(void);/**操作结果:构造⼀个空队列Q */void DestoryQueue(PQUEUE pQ);/**初始条件:队列已经存在* 操作结果:队列被销毁*/void ClearQueue(PQUEUE pQ);/**初始条件:队列已经存在* 操作结果:将队列清空*/bool QueueEmpty(PQUEUE pQ);/**初始条件:队列已经存在* 操作结果:若队列为空,返回TURE,否则返回FALSE*/bool QueueFull(PQUEUE pQ);/**初始条件:队列已存在* 操作结果:若队列已满,返回TURE,否则返回FALSE*/int QueueHead(PQUEUE pQ,int val);/**初始条件:队列存在且⾮空* 操作结果:返回队列头元素*/bool EnQueue(PQUEUE pQ,int val);/**初始条件:队列已存在* 操作结果:在队尾插⼊元素*/bool DeQueue(PQUEUE pQ,int *pVal);/**初始条件:队列存在且⾮空* 操作结果:删除队头元素,并返回其值*/void QueueTraverse(PQUEUE pQ);/**初始条件:队列存在且⾮空* 操作结果:输出队列元素*/int N; //N ⽤于在各个函数之间传递队列的实际长度int main(){int t;printf("请输⼊队列长度:"); //这⾥⽤ N + 1 是因为输⼊的队列长度是实际元素的个数,因为循环队列会浪费⼀个元素,所以令队列的实际长度为 N + 1 ⽅便使⽤ scanf("%d",&t);N=t+1;PQUEUE pQ=InitQueue();int i,n;for(i=0;i<N-1;i++){ //⽤户输⼊的队列长度为 N - 1scanf("%d",&n);EnQueue(pQ,n);}QueueTraverse(pQ);int val;DeQueue(pQ,&val);QueueTraverse(pQ);printf("出队元素为:%d",val);}PQUEUE InitQueue(void) //构造⼀个空队列{PQUEUE pQ=(PQUEUE)malloc(sizeof(QUEUE)); //这⾥必须⽤ malloc 函数,否则⽣成的就是⼀个局部变量。

循环队列

循环队列

循环队列(C语言版)线性结构的主要操作就是插入和删除,我们前面讲过的顺序线性表、单链表、双链表都没有限制插入和删除操作的位置。

如果我们限定插入和删除操作在线性表的同一端进行那么这种结构就是栈;如果限定插入在一端而删除在另一端,这种结构就是对列;栈的特点是先进后出(FILO)而对列是先进先出(FIFO)。

进行插入的一端叫队尾,删除的一端叫队头。

队列的实现可以用顺序线性表也可以用链表。

在实际使用中有一种更常用的队列叫循环队列。

循环队列是把队列的头和尾在逻辑上连接起来,构成一个环。

循环队列中首尾相连,分不清头和尾,此时需要两个指示器分别指向头部和尾部。

插入就在尾部指示器的指示位置处插入,删除就在头部指示器的指示位置删除。

循环队列在插入时也要判断其是否已满,删除时要判断其是否已空。

为空的条件比较简单当头部指示器和尾部指示器指向同一个位置时表示循环队列为空;因为尾部指示器指示的是最后一个元素的下一个位置,所以循环队列已满时头部指示器和尾部指示器也指向同一个位置,为了区分这两种状况有两种方法,一种增加一个标识变量来区分,另一种损失循环队列中的一个元素,即头和尾之间的位置不用,此时循环队列为满的条件变成头部指示器加1等于尾部指示器;为空的条件成为头部指示器和尾部指示器指向同一位置。

循环队列的首尾相连是通过取余操作来实现的,把头和尾的位置都除以队列最大长度然后取余。

当到达尾部及最后一个位置时再加1就成了队列的长度刚好可以整除余0即又回到了队头。

循环队列的主要操作:(1)创建循环队列(2)初始化循环队列(3)判断循环队列是否为空(4)判断循环队列是否为满(5)入队(6)出队Microsoft Visual Studio .NET 2003下的程序:C代码1. #include<stdio.h>2.3.#define MAXSIZE 1004.typedef struct5.{6.int elem[MAXSIZE];7.int front,rear;8.}Quque; //定义队头9.10. int initQue(Quque **q) //初始化11. {12. (*q)->front=0;13. (*q)->rear=0;14. }15.16. int isFull(Quque *q)17. {18. if(q->front==(q->rear+1)%MAXSIZE) //判满刘勉刚19. return 1;20. else21. return 0;22. }23. int insertQue(Quque **q,int elem)24. {25. if(isFull(*q)) return -1;26. (*q)->elem[(*q)->rear]=elem;27. (*q)->rear=((*q)->rear+1)%MAXSIZE; //插入28. return 0;29. }30. int isEmpty(Quque *q)31. {32. if(q->front==q->rear) //判空33. return 1;34. else35. return 0;36. }37. int deleteQue(Quque ** q,int *pelem)38. {39. if(isEmpty(*q))40. return 0;41. *pelem=(*q)->elem[(*q)->front];42. (*q)->front =((*q)->front +1)%MAXSIZE;43. return 0;44. }45.46. int main(void)47. {48. int i=0,elem;49. Quque *q=(Quque *)malloc(sizeof(Quque));50. initQue(&q);51. for(;i<10;i++)52. {53. insertQue(&q,i);54. }55. for(i=0;i<10;i++)56. {57. deleteQue(&q,&elem);58. printf("%d\n",elem);59. }60. system("pause");61. return 0;62. }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四队列(循环队列的创建、添加和删除操作)(2学时)
1.实验目的:掌握循环队列的基本操作,并对其进行简单应用。

2.实验内容:
假设循环队列的最大长度为7,现在依次将以下数据入队列:{7,5,3,9,2,4};
接着进行3次出队列的操作,再将15、18、16这三个数据入队列,最后从对头到队尾依次输出队列中的元素。

3.预习要求:
事先预习书上第3.4.3节有关循环队列的内容,包括:
1、理解什么是循环队列;
2、为何要构造循环队列;
3、如何构造循环队列;
4、如何删除对头元素;
5、如何在队列中增加元素;
6、如何判断循环队列的空和满的状态
4.实验步骤:(1)审清题意,分析并理出解决问题的基本思路。

(2)根据基本思路,设计好程序的算法。

(3)根据算法编写源程序。

(4)在计算机上编译程
序,检验程序的可运行性
5. 实验报告:
(1)实验目的;
(2)实验内容;
(3)实验步骤:画图(如书上P64页图3.14,仿照此图,画出实验内容3的操作),并程序调试过程和结果;
(4)总结。

相关文档
最新文档