数据结构 实验4 循环队列的实现和运算
循环队列的基本操作
实验四循环队列的基本操作实验目的: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(){(由学生填写)}实验用测试数据和相关结果分析:(由学生填写)实验总结:(由学生填写)。
数据结构上机4_循环队列
实验四队列(循环队列的创建、添加和删除操作)
1.实验目的:掌握循环队列的基本操作,并对其进行简单应用。
2.实验内容:
假设循环队列的最大长度为7,现在依次将以下数据入队列:{7,5,3,9,2,4};
接着进行3次出队列的操作,再将15、18这两个数据入队列,最后从对头到队尾依次输出队列中的元素。
3.实验步骤:
源代码:
运行结果;
4.总结
在C语言中不能用动态分配的一维数组来实现循环队列。
如果用户的应用程序中设有循环队列,则必须为他设定一个最大队列长度;若用户无法预估队列的最大长度,则宜采用链队列。
【数据结构】循环队列的实现
【数据结构】循环队列的实现//111111111111111111111111111第一部分1111111111111111111111111#include<stdio.h>#define MAXQSIZE 5#define ERROR 0#define OK 1;//原来我们定义一个int类型的ElemType,//这次我们定义一个int类型的QElemType,typedef int QElemType;typedef int Status;//定义循环队列的结构体typedef struct SqQueue{QElemType *base;int front;//头指针,说的是指针,其实就是一个整型的变量,//变量加1,相当于指针加1,不是真正的指针,深入理解int rear;//尾指针}SqQueue;//111111111111111111111111111第一部分结束1111111111111111111111111//222222222222222222222222222第二部分2222222222222222222222222222 //循环队列的操作//初始化Status InitSQueue(SqQueue *SQ){//申请MAXQSIZE个连续的空间,将空间的首地址赋给base指针SQ->base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));//申请失败,退出if(!SQ->base)exit(ERROR);//刚开始,头指针和尾指针都等于0,//这里再次理解,front和rear其实不是真正的指针,指针式地址//这里仅仅是定义了整型变量,当指针的来使用。
//同胞们,要好好理解啊SQ->front = SQ->rear = 0;printf("初始化完毕,申请的空间是:%d个\n",MAXQSIZE);return OK;}// 入队(插入尾元素)Status EnSQueue(SqQueue *SQ,QElemType e){//先要判断,如果循环队列满了,就不能再插入了//同学们思考,这里如果满了,是否可以再申请空间//(答案是可以的,给你们空间去发挥)if((SQ->rear + 1)%MAXQSIZE == SQ->front){printf("我已经没空间了,可怜可怜我把,别进了!\n");printf("我剩余的一个空间,还要区别队空和队满的标志了!\n");return ERROR;}//看到了吧,这里的SQ->rear其实是个整型,作为数组的下标来用//类似于指针的作用SQ->base[SQ->rear] = e;//一定要注意,循环队列指针加1,一定要对MAXQSIZE求余,因为是循环的//深入理解SQ->rear = (SQ->rear + 1)%MAXQSIZE;return OK;}// 出队(删除头元素)Status DeSQueue(SqQueue *SQ,QElemType *e){//先要判断,如果循环队列是否空了,空队列没元素可出if(SQ->rear == SQ->front){printf("我已经没元素了,你还让我出啥呀!\n");return ERROR;}*e = SQ->base[SQ->front];//一定要注意,循环队列指针加1,一定要对MAXQSIZE求余,因为是循环的//深入理解SQ->front = (SQ->front + 1)%MAXQSIZE;return OK;}//遍历链队:Status visitSQueue(SqQueue *SQ){//这里遍历,就相当于输出数组int i;int length;printf("现在队列的元素值为:\n");//深入理解这个for循环for(i = SQ->front;i < SQ->rear;i++){printf("%d ",SQ->base[i]);}printf("\n");return OK;}//求队列长度:Status Queuelength(SqQueue *SQ){//这里给你们空间去发挥printf("等你来完成了,别偷懒啊,我可是全程监控了!\n");return OK;}//222222222222222222222222222第二部分结束2222222222222222222222222222//33333333333333333333333333333第三部分3333333333333333333333333333 void main(){SqQueue *SQ;QElemType e;int temp;int returnvalue;printf("1:初始化循环队列----------------------2:入队\n");printf("3:出队-------------------4:返回长度\n");printf("5:退出\n");while(1){printf("请输入要操作的编号:\n");scanf("%d",&temp);//如果是1表示头插法建立链表if(temp == 1){InitSQueue(SQ);}//如果是2入队if(temp == 2){printf("请输入要入队元素值:\n");scanf("%d",&e);//入队操作returnvalue = EnSQueue(SQ,e);if(returnvalue == 1){visitSQueue(SQ);}}//如果是3,出队if(temp == 3){//调用出栈的函数returnvalue = DeSQueue(SQ,&e);if(returnvalue == 1){printf("你出队的元素是:%d\n",e);visitSQueue(SQ);}}//返回长度if(temp == 4){Queuelength(SQ);}//操作结束if(temp == 5){exit(1);}}}。
数据结构实验4:C++实现循环队列
数据结构实验4:C++实现循环队列实验44.1 实验⽬的熟练掌握队列的顺序存储结构和链式存储结构。
熟练掌握队列的有关算法设计,并在循环顺序队列和链队列上实现。
根据具体给定的需求,合理设计并实现相关结构和算法。
4.2 实验要求4.2.1 循环顺序队列的实验要求循环顺序队列结构和运算定义,算法的实现以库⽂件⽅式实现,不得在测试主程序中直接实现;实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件⼯程要求;程序有适当的注释。
4.3 实验任务4.3.1 循环顺序队列实验任务编写算法实现下列问题的求解。
<1>初始化⼀个队列。
<2>判断是否队空。
<3>判断是否队满。
设队列最⼤长度:MaxLen=100第⼀组数据:⼊队n个元素,判断队满第⼆组数据:⽤循环⽅式将1到99,99个元素⼊队,判队满<4>⼊队第⼀组数据:4,7,8,12,20,50第⼆组数据:a,b,c,d,f,g<5>出队<6>取队头元素<7>求当前队列中元素个数<8>编写算法实现①初始化空循环队列;②当键盘输⼊奇数时,此奇数⼊队;③当键盘输⼊偶数时,队头出队;④当键盘输⼊0时,算法退出;⑤每当键盘输⼊后,输出当前队列中的所有元素。
4.5 运⾏结果截图及说明图1 测试(1)、(2)、(3)、(5)、(6)、(7)图2 测试(4)图3 测试(4)图4 测试(8)4.6 附源代码1// stdafx.h : include file for standard system include files,2// or project specific include files that are used frequently, but3// are changed infrequently4//56#if !defined(AFX_STDAFX_H__8FA49CDF_FC99_4984_AB37_46921F7ED357__INCLUDED_)7#define AFX_STDAFX_H__8FA49CDF_FC99_4984_AB37_46921F7ED357__INCLUDED_89#if _MSC_VER > 100010#pragma once11#endif// _MSC_VER > 10001213 #include <stdc++.h>1415using namespace std;1617 typedef int elementType;18 typedef char elementType1;19const int maxn = 100;2021// TODO: reference additional headers your program requires here2223//{{AFX_INSERT_LOCATION}}24// Microsoft Visual C++ will insert additional declarations immediately before the previous line.2526#endif// !defined(AFX_STDAFX_H__8FA49CDF_FC99_4984_AB37_46921F7ED357__INCLUDED_)1// _SeqCircleQueue.h: interface for the _SeqCircleQueue class.2//3//////////////////////////////////////////////////////////////////////45#if !defined(AFX__SEQCIRCLEQUEUE_H__FCBC0603_27E1_4352_833C_6BED9B418B96__INCLUDED_) 6#define AFX__SEQCIRCLEQUEUE_H__FCBC0603_27E1_4352_833C_6BED9B418B96__INCLUDED_78#if _MSC_VER > 10009#pragma once10#endif// _MSC_VER > 10001112class _SeqCircleQueue13 {14public:15 _SeqCircleQueue();16virtual ~_SeqCircleQueue();17bool emptySeqCircleQueue();18bool fullSeqCircleQueue();19bool enQueue( elementType value );20bool deQueue( elementType &value );21bool getFront( elementType &value );22int length();23void oddOrEven( elementType value );24 friend ostream &operator<<( ostream &os, _SeqCircleQueue &scq )25 {26if( ( scq._front - 1 ) % maxn == scq._rear )27return os;28int column = 0;29for( int i = scq._front; i % maxn != scq._rear; i = ( i + 1 ) % maxn )30 {31 os << setw(3) << setiosflags(ios::left) << scq.data[i] << "";32 column ++;33if( column % 10 == 0 )34 os << endl;35 }36 os << endl;37 }39 elementType data[maxn];40int _front;41int _rear;4243 };4445#endif// !defined(AFX__SEQCIRCLEQUEUE_H__FCBC0603_27E1_4352_833C_6BED9B418B96__INCLUDED_) 1// _SeqCircleQueue.cpp: implementation of the _SeqCircleQueue class.2//3//////////////////////////////////////////////////////////////////////45 #include "stdafx.h"6 #include "_SeqCircleQueue.h"78//////////////////////////////////////////////////////////////////////9// Construction/Destruction10//////////////////////////////////////////////////////////////////////1112 _SeqCircleQueue::_SeqCircleQueue()13 {14 _front = _rear = 0;15 }1617 _SeqCircleQueue::~_SeqCircleQueue()18 {19 ios::sync_with_stdio(false);20 cout << "The _SeqCircleQueue destruction has been called!" << endl;21 }2223bool _SeqCircleQueue::emptySeqCircleQueue()24 {25return _front == _rear;26 }2728bool _SeqCircleQueue::fullSeqCircleQueue()29 {30return ( _rear + 1 ) % maxn == _front;31 }3233bool _SeqCircleQueue::enQueue( elementType value )34 {35if( fullSeqCircleQueue() )36 {37 cerr << "Seq-Circle-Queue is full!Error in _SeqCircleQueue::enQueue()!" << endl;38return false;39 }40 data[_rear] = value;41 _rear = ( _rear + 1 ) % maxn;42return true;43 }4445bool _SeqCircleQueue::deQueue( elementType &value )46 {47if( emptySeqCircleQueue() )48 {49 cerr << "Seq-Circle-Queue is empty!Error in _SeqCircleQueue::popFront()!" << endl;50return false;51 }52 value = data[_front];53 _front = ( _front + 1 ) % maxn;54return true;55 }5657bool _SeqCircleQueue::getFront( elementType &value )58 {59if( emptySeqCircleQueue() )60 {61 cerr << "Seq-Circle-Queue is empty!Error in _SeqCircleQueue::getFront()!" << endl;62return false;63 }64 value = data[_front];65return true;66 }6768int _SeqCircleQueue::length()69 {70if( emptySeqCircleQueue() )72 cerr << "Seq-Circle-Queue is empty!Error in _SeqCircleQueue::length()!" << endl;73return -1;74 }75return ( _rear - _front + maxn ) % maxn;76 }7778void _SeqCircleQueue::oddOrEven( elementType value )79 {80if( value & 1 )81 {82 enQueue(value);83 cout << value << " will be added to the queue!" << endl;84 cout << (*this);85 }86else if( !( value & 1) && value != 0 )87 {88 elementType x;89 deQueue(x);90 cout << x << " has been deleted from the queue!" << endl;91 cout << (*this);92 }93else//if( value == 0 )94 {95 cout << "The _SeqCircleQueue::oddOrEven() has been stoped!" << endl;96return;97 }98 }1// charSeqCircleQueue.h: interface for the charSeqCircleQueue class.2//3//////////////////////////////////////////////////////////////////////45#if !defined(AFX_CHARSEQCIRCLEQUEUE_H__FBB4F8DD_2EF9_43A6_8E23_FD7E4C56908E__INCLUDED_)6#define AFX_CHARSEQCIRCLEQUEUE_H__FBB4F8DD_2EF9_43A6_8E23_FD7E4C56908E__INCLUDED_78#if _MSC_VER > 10009#pragma once10#endif// _MSC_VER > 10001112class charSeqCircleQueue13 {14public:15 charSeqCircleQueue();16virtual ~charSeqCircleQueue();17bool emptyCharSeqCircleQueue();18bool fullCharSeqCircleQueue();19bool enQueue( elementType1 value );20bool deQueue( elementType1 &value );21bool getFront( elementType1 &value );22int length();23 friend ostream &operator<<( ostream &os, charSeqCircleQueue &cscq )24 {25if( ( cscq._front - 1 ) % maxn == cscq._rear )26return os;27int column = 0;28for( int i = cscq._front; i % maxn != cscq._rear; i = ( i + 1 ) % maxn )29 {30 os << setw(3) << setiosflags(ios::left) << cscq.data[i] << "";31 column ++;32if( column % 10 == 0 )33 os << endl;34 }35 os << endl;36 }37private:38 elementType1 data[maxn];39int _front;40int _rear;4142 };4344#endif// !defined(AFX_CHARSEQCIRCLEQUEUE_H__FBB4F8DD_2EF9_43A6_8E23_FD7E4C56908E__INCLUDED_) 1// charSeqCircleQueue.cpp: implementation of the charSeqCircleQueue class.3//////////////////////////////////////////////////////////////////////45 #include "stdafx.h"6 #include "charSeqCircleQueue.h"78//////////////////////////////////////////////////////////////////////9// Construction/Destruction10//////////////////////////////////////////////////////////////////////1112 charSeqCircleQueue::charSeqCircleQueue()13 {14 _front = _rear = 0;15 }1617 charSeqCircleQueue::~charSeqCircleQueue()18 {19 ios::sync_with_stdio(false);20 cout << "The charSeqCircleQueue destruction has been called!" << endl;21 }2223bool charSeqCircleQueue::emptyCharSeqCircleQueue()24 {25return _front == _rear;26 }2728bool charSeqCircleQueue::fullCharSeqCircleQueue()29 {30return ( _rear + 1 ) % maxn == _front;31 }3233bool charSeqCircleQueue::enQueue( elementType1 value )34 {35if( fullCharSeqCircleQueue() )36 {37 cerr << "Seq-Circle-Queue is full!Error in charSeqCircleQueue::::enQueue()!" << endl; 38return false;39 }40 data[_rear] = value;41 _rear = ( _rear + 1 ) % maxn;42return true;43 }4445bool charSeqCircleQueue::deQueue( elementType1 &value )46 {47if( emptyCharSeqCircleQueue() )48 {49 cerr << "Seq-Circle-Queue is empty!Error in charSeqCircleQueue::popFront()!" << endl; 50return false;51 }52 value = data[_front];53 _front = ( _front + 1 ) % maxn;54return true;55 }5657bool charSeqCircleQueue::getFront( elementType1 &value )58 {59if( emptyCharSeqCircleQueue() )60 {61 cerr << "Seq-Circle-Queue is empty!Error in charSeqCircleQueue::::getFront()!" << endl; 62return false;63 }64 value = data[_front];65return true;66 }6768int charSeqCircleQueue::length()69 {70if( emptyCharSeqCircleQueue() )71 {72 cerr << "Seq-Circle-Queue is empty!Error in charSeqCircleQueue::::length()!" << endl; 73return -1;74 }75return ( _rear - _front + maxn ) % maxn;76 }4.7 调试过程中出现的bug总结注意细节!。
Python实现数据结构-循环队列的操作方法
Python实现数据结构-循环队列的操作⽅法今天我们来到了循环队列这⼀节,之前的⽂章中,我介绍过了,这是最简单的实现⽅法。
但是,我们都知道,在列表中删除第⼀个元素和删除最后⼀个元素花费的时间代价是不⼀样的,删除列表的第⼀个元素,那么在它之后的所有元素都要进⾏移动。
所以当列表特别长的时候,这个代价就⽐较明显了。
我们本⽂介绍的循环队列可以避免这个问题,同样我们上篇⽂章提到的⽤链表实现的⽅法也可以避免。
下⾯,我们来介绍循环队列。
循坏队列循环队列,就是将普通的队列⾸尾连接起来,形成⼀个环状,并分别设置⾸尾指针,⽤来指明队列的头和尾。
每当我们插⼊⼀个元素,尾指针就向后移动⼀位,当然,在这⾥我们队列的最⼤长度是提前定义好的,当我们弹出⼀个元素,头指针就向后移动⼀位。
这样,列表中就不存在删除操作,只有修改操作,从⽽避免了删除前⾯节点造成的代价⼤的问题。
好,话不多说,我们⽤代码来实现⼀下class Loopqueue:def __init__(self, length):self.head = 0self.tail = 0self.maxSize = lengtht = 0self.__list = [None]*length这⾥同样,我们定义⼀个队列类,在实例化循环队列的时候,要求指定队列的⼤⼩,除了⾸尾指针以及队列最⼤长度之外,我们还声明⼀个表⽰队列当前长度的属性cnt。
接下来我们给队列增加⼀些操作:判空def isEmpty(self):return t == 0判满def isFull(self):return t == self.maxSize添加元素def push(self, data):if self.isFull():return Falseif self.isEmpty():self.__list[0] = dataself.head = 0self.tail = 0t = 1return Trueself.tail = (self.tail+1)%self.maxSizet += 1self.__list[self.tail] = datareturn True弹出元素def pop(self):if self.isEmpty():return Falsedata = self.__list[self.head]self.head = (self.head+1)%self.maxSizet -= 1return data清空队列def clear(self):self.head = 0self.tail = 0t = 0return True定义len和print函数def __len__(self):return tdef __str__(self):s = ''for i in range(t):index = (i + self.head) % self.maxSizes += str(self.__list[index])+' 'return sOK,我们的循环队列类就定义好了,如果你看过介绍队列的⽂章,就会发现循环队列和普通队列的操作在逻辑上还是有⼀些相似的。
循环队列的基本操作
实验四循环队列的基本操作实验目的: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(){(由学生填写)}实验用测试数据和相关结果分析:(由学生填写)实验总结:(由学生填写)。
数据结构实验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指针指向数组的第一个位置。
通过循环队列的实现和运算,可以高效地进行队列的操作,从而提高算法的执行效率。
在实际应用中,循环队列常被用于实现缓冲区、进程调度等场景。
数据结构:循环队列及其基本操作的实现
数据结构:循环队列及其基本操作的实现/*** 循环队列* 队列设置first指针直接指向队列头部元素,tail尾指针指向队列最后⼀个元素的后⼀个,即队列中总是预留⼀个空位*/class CircleQueue implements Queue<Integer>{private Integer[] queueArray = null;private int first;private int tail;private int maxSize;public CircleQueue(int max){this.maxSize=max+1;this.queueArray = new Integer[maxSize];}@Overridepublic int size() {return (tail-first+maxSize)%maxSize;}@Overridepublic boolean isEmpty() {return tail==first;}@Overridepublic boolean contains(Object o) {Integer integer = (Integer)o;for (int i = first; i!=tail; i++) {if (i==queueArray.length){i=0;}if (integer.equals(queueArray[i])){return true;}}return false;}@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {int temFirst = first;@Overridepublic boolean hasNext() {return tail!=temFirst;}@Overridepublic Integer next() {int num = queueArray[temFirst];temFirst = (temFirst+1)%maxSize;return num;}};}@Overridepublic boolean add(Integer integer) {if ((tail+1)%maxSize==first){System.out.println("队列已满,⽆法添加");return false;}queueArray[tail]=integer;tail = (tail+1)%maxSize;return true;}@Overridepublic Integer poll() {if(isEmpty()){throw new RuntimeException("队列为空");}int result = queueArray[first];first = (first+1)%maxSize;return first;}@Overridepublic Integer peek() {return queueArray[first];}}public static void main(String[] args) {CircleQueue circleQueue = new CircleQueue(5);Scanner scanner = new Scanner(System.in);while (true){System.out.println("1:添加元素");System.out.println("2:取出元素");System.out.println("3:查看头元素");System.out.println("4:遍历队列");System.out.println("5:查看元素数量");System.out.println("6:是否为空");int commend = scanner.nextInt();switch (commend){case 1:{System.out.println("请输出⼀个元素");int num = scanner.nextInt();circleQueue.add(num);break;}case 2:{System.out.println(circleQueue.poll());break;}case 3:{System.out.println(circleQueue.peek());break; }case 4:{for (Integer integer : circleQueue) {System.out.printf("%d\t",integer);}System.out.println();break;}case 5:{System.out.println(circleQueue.size());break; }case 6:{System.out.println(circleQueue.isEmpty());break;}}}}。
数据结构实现循环队列的两种方法
数据结构实现循环队列的两种⽅法⼀、包含队列元素nItem⽅式:1package data.struct.algorithm;234//定义队列,包含五个域值5class Queuex {6private int maxSize;7private int[] queueArray;8private int front;9private int rear;10private int nItem;1112public Queuex(int s) {13 maxSize = s;14 queueArray = new int[maxSize];15 front = 0;16 rear = -1;17 nItem = 0;18 }1920//队列尾部插⼊元素21public void insert(int value) {22if(nItem==maxSize){23throw new RuntimeException("队列满了,不能插⼊数据了");24 }25if (rear == maxSize - 1) {26 rear = -1;27 }28 queueArray[++rear] = value;29 nItem++;30 }3132//队头删除元素33public int remove() {34if(nItem==0){35throw new RuntimeException("队列中没有元素了,不能进⾏删除操作了");36 }37int value = queueArray[front++];38if (front == maxSize) {39 front = 0;40 }41 nItem--;42return value;43 }4445//查看队头元素46public int peek() {47return queueArray[front];48 }4950//判断队列是否为空51public boolean isEmpty() {52return nItem == 0;53 }5455//判断队满56public boolean isFull() {57return nItem == maxSize;58 }5960//获取队列⼤⼩61public int getSize() {62return nItem;63 }64 }6566public class QueueApp {6768/**69 * @param args70*/71public static void main(String[] args) {7273 Queuex theQueue=new Queuex(10);74 theQueue.insert(3);75 theQueue.insert(13);76 theQueue.insert(23);77 theQueue.insert(33);78 theQueue.insert(43);79 theQueue.insert(53);80 System.out.println(theQueue.peek());81 System.out.println(theQueue.remove());82 theQueue.insert(63);83 theQueue.insert(73);84 theQueue.insert(83);85 theQueue.insert(93);86// theQueue.insert(103);87 System.out.println(theQueue.peek());88while(!theQueue.isEmpty()){89 System.out.print(theQueue.remove()+" ");90 }91 System.out.println();9293 }9495 }⼆、不包含队列元素nItem⽅式:1package data.struct.algorithm;23//定义队列,包含四个域值,不包含队列⼤⼩nItems4//判断队空:rear==front5//判断队空:(rear+1)%maxSize==front,即队头指针在队尾指针的下⼀个位置6class Queuey {7private int maxSize;8private int[] queueArray;9private int front;10private int rear;1112public Queuey(int s) {13 maxSize = s;14 queueArray = new int[maxSize];15 front = 0;16 rear = 0;17 }1819// 队列尾部插⼊元素20public void insert(int value) {21if (this.isFull()) {22throw new RuntimeException("队满");23 }24 queueArray[rear] = value;25 rear=(rear+1)%maxSize;26 }2728// 队头删除元素29public int remove() {30if (this.isEmpty()) {31throw new RuntimeException("队列中没有元素了,不能进⾏删除操作了");32 }33int value = queueArray[front];34 front = (front + 1) % maxSize;35return value;36 }3738// 查看队头元素39public int peek() {40return queueArray[front];41 }4243// 判断队列是否为空44public boolean isEmpty() {45return rear == front;46 }4748// 判断队满49public boolean isFull() {50return (rear + 1) % maxSize == front;51 }5253// 获取队列⼤⼩54public int getSize() {55return (rear - front + maxSize) % maxSize;56 }57 }5859public class CopyOfQueueApp {6061/**62 * @param args63*/64public static void main(String[] args) {6566 Queuey theQueue = new Queuey(5);67 theQueue.insert(13);68 theQueue.insert(23);69 theQueue.insert(33);70 theQueue.insert(43);71// theQueue.insert(63);72 System.out.println(theQueue.getSize());73 System.out.println(theQueue.remove());74 System.out.println(theQueue.remove());75 theQueue.insert(63);76 theQueue.insert(73);77 System.out.println(theQueue.peek());78while (!theQueue.isEmpty()) {79 System.out.print(theQueue.remove() + " ");80 }81 System.out.println();8283 }8485 }三、⽤链表来实现队列存放结点:1public class Node {23public int data;4public Node next;5public Node(int data,Node next){6this.data=data;7this.next=next;8 }9 }定义的链表的操作:1public class LinkList {23private Node head;4private Node tail;5public LinkList(){6 head=null;7 tail=null;8 }9public void insertLast(int data){10 Node newNode=new Node(data, null);11if(isEmpty()){12 head=newNode;13 }14else {15 tail.next=newNode;16 }17 tail=newNode;18 }19public int deleteHead(){20if(head.next==null){21 tail=null;22return head.data;23 }24if(head!=null){2526 Node tempNode=head;27 head=head.next;28return tempNode.data;29 }30else {31throw new RuntimeException("不能删除元素了");32 }33 }34public boolean isEmpty(){35return head==null;36 }3738 }链表模拟的队列1//⽤的是insertLast()和deleteHead()⽅法,即在尾部插⼊,在链表头删除 2public class LinkQueue {34private LinkList linkList;5public LinkQueue(){6 linkList=new LinkList();7 }8public void push(int data){9 linkList.insertLast(data);10 }11public int pop(){12return linkList.deleteHead();13 }14public boolean isEmpty(){15return linkList.isEmpty();16 }17 }测试类1public class QueuqTest {23/**4 * @param args5*/6public static void main(String[] args) {78 LinkQueue linkQueue=new LinkQueue();9 linkQueue.push(10);10 linkQueue.push(20);11 linkQueue.push(30);12 linkQueue.push(40);13 System.out.println(linkQueue.pop());14 }15 }。
队列(循环队列)的表示和实现
浙江大学城市学院实验报告课程名称数据结构基础实验项目名称实验八队列(循环队列)的表示和实现学生姓名专业班级学号实验成绩指导老师(签名)日期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、掌握栈的结构特性及其⼊栈,出栈操作;2、掌握队列的结构特性及其⼊队、出队的操作,掌握循环队列的特点及其操作。
⼆、实验预习说明以下概念1、顺序栈:2、链栈:3、循环队列:4、链队三、实验内容和要求1、阅读下⾯程序,将函数Push和函数Pop补充完整。
要求输⼊元素序列1 2 3 4 5 e,运⾏结果如下所⽰。
#include#include#define ERROR 0#define OK 1#define STACK_INT_SIZE 10 /*存储空间初始分配量*/#define STACKINCREMENT 5 /*存储空间分配增量*/typedef int ElemType; /*定义元素的类型*/typedef struct{ElemType *base; /*定义栈底部指针*/ElemType *top; /*定义栈顶部指针*/int stacksize; /*当前已分配的存储空间*/}SqStack;int InitStack(SqStack *S); /*构造空栈*/int push(SqStack *S,ElemType e); /*⼊栈操作*/int Pop(SqStack *S,ElemType *e); /*出栈操作*/int CreateStack(SqStack *S); /*创建栈*/void PrintStack(SqStack *S); /*出栈并输出栈中元素*/int InitStack(SqStack *S){S->base=(ElemType *)malloc(STACK_INT_SIZE *sizeof(ElemType)); if(!S->base) return ERROR;S->top=S->base;int Push(SqStack *S,ElemType e){if(S->top-S->base>=S->stacksize){S->base=(ElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(ElemType)); S->top=S->base+S->stacksize;S->stacksize+=STACKINCREMENT;}*S->top++=e;return 1}/*Push*/int Pop(SqStack *S,ElemType *e){if(S->top!=S->base){*e=*--S->top;return 1;}elsereturn 0;}/*Pop*/int CreateStack(SqStack *S){int e;if(InitStack(S))printf("Init Success!\n");else{printf("Init Fail!\n");return ERROR;}printf("input data:(Terminated by inputing a character)\n"); while(scanf("%d",&e))Push(S,e);return OK;}/*CreateStack*/while(Pop(S,&e))printf("%3d",e);}/*Pop_and_Print*/int main(){SqStack ss;printf("\n1-createStack\n");CreateStack(&ss);printf("\n2-Pop&Print\n");PrintStack(&ss);return 0;}●算法分析:输⼊元素序列1 2 3 4 5,为什么输出序列为5 4 3 2 1?体现了栈的什么特性?2、在第1题的程序中,编写⼀个⼗进制转换为⼆进制的数制转换算法函数(要求利⽤栈来实现),并验证其正确性。
循环队列详解及队列的顺序表示和实现
循环队列详解及队列的顺序表⽰和实现循环队列——队列的顺序表⽰和实现前⾯分析顺序队的时候,我们知道,顺序队存在”假溢出”的问题,这个问题有时会造成很⼤的内存浪费,循环队列就是为了解决这个问题⽽提出地⼀个很巧妙的办法.循环队列和顺序队列的主要区别在于:循环队列将顺序队列臆造成⼀个环状空间.在操作上这种异同体现在:相同点:在顺序队列和循环队列中,进⾏出队、⼊队操作时,队⾸、队尾指针都要加 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));}运⾏截图:感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。
数据结构 实验4 循环队列的实现和运算
}
5、测试数据与实验结果(可以抓图粘贴)(1)菜单显示:
(2)入队:
(3)队满(已入队9个元素):
(4)出队:
(5)队空(已出队9个元素):
(6)显示队中的元素:
(7)求队长:
6、结果分析与实验体会
本次实验是参考了范例程序,经过自己的改写,从而实现要求。
先做简单的输出,一步步的再做其它格式的设置。
在实验的过程中,我加深了对队列各种操作的理解,因为队列是“先进先出”的操作受限制的线性表,一般队列只允许在队尾进行插入操作,在队头进行删除操作,元素之间存在一对一的关系,本程序的设计过程也是对前面线性表知识的巩固。
再者,用链式存储结构实现这个程序,实际上是设计一个带有头指针(front)和尾指针(rear)的单向链表,此单向链表没有头结点,头尾指针指的是同一个单向链表中的首尾结点,所以,从链队列的整体结构考虑,一般讲这两个指针封装在一个结构体中。
队列是一种应用广泛的数据结构,凡具有其特点的需要排队处理的问题,都可以使用它来处理。
实验四循环队列基本操作及相关算法的实现
实验四循环队列基本操作及相关算法的实现一、实验目的:掌握循环队列的基本操作及在顺序存储结构上的实现。
二、实验环境: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语⾔实现)⽣活中有⾮常多队列的影⼦,⽐⽅打饭排队,买⽕车票排队问题等,能够说与时间相关的问题,⼀般都会涉及到队列问题;从⽣活中,能够抽象出队列的概念,队列就是⼀个能够实现“先进先出”的存储结构。
队列分为链式队列和静态队列;静态队列⼀般⽤数组来实现,但此时的队列必须是循环队列,否则会造成巨⼤的内存浪费;链式队列是⽤链表来实现队列的。
这⾥讲的是循环队列,⾸先我们必须明确以下⼏个问题⼀、循环队列的基础知识1.循环队列须要⼏个參数来确定循环队列须要2个參数,front和rear2.循环队列各个參数的含义(1)队列初始化时,front和rear值都为零;(2)当队列不为空时,front指向队列的第⼀个元素,rear指向队列最后⼀个元素的下⼀个位置;(3)当队列为空时,front与rear的值相等,但不⼀定为零;3.循环队列⼊队的伪算法(1)把值存在rear所在的位置;(2)rear=(rear+1)%maxsize ,当中maxsize代表数组的长度;程序代码:bool Enqueue(PQUEUE Q, int val){if(FullQueue(Q))return false;else{Q->pBase[Q->rear]=val;Q->rear=(Q->rear+1)%Q->maxsize;return true;}}4.循环队列出队的伪算法(1)先保存出队的值;(2)front=(front+1)%maxsize ,当中maxsize代表数组的长度;程序代码:bool Dequeue(PQUEUE Q, int *val){if(EmptyQueue(Q)){return false;}else{*val=Q->pBase[Q->front];Q->front=(Q->front+1)%Q->maxsize;return true;}}5.怎样推断循环队列是否为空if(front==rear)队列空;else队列不空;bool EmptyQueue(PQUEUE Q){if(Q->front==Q->rear) //推断是否为空return true;elsereturn false;}6.怎样推断循环队列是否为满这个问题⽐較复杂,如果数组的存数空间为7,此时已经存放1,a,5,7,22,90六个元素了,如果在往数组中加⼊⼀个元素,则rear=front;此时,队列满与队列空的推断条件front=rear同样,这种话我们就不能推断队列究竟是空还是满了;解决问题有两个办法:⼀是添加⼀个參数,⽤来记录数组中当前元素的个数;第⼆个办法是,少⽤⼀个存储空间,也就是数组的最后⼀个存数空间不⽤,当(rear+1)%maxsiz=front时,队列满;bool FullQueue(PQUEUE Q){if(Q->front==(Q->rear+1)%Q->maxsize) //推断循环链表是否满,留⼀个预留空间不⽤return true;elsereturn false;}附录:queue.h⽂件代码:#ifndef __QUEUE_H_#define __QUEUE_H_typedef struct queue{int *pBase;int front; //指向队列第⼀个元素int rear; //指向队列最后⼀个元素的下⼀个元素int maxsize; //循环队列的最⼤存储空间}QUEUE,*PQUEUE;void CreateQueue(PQUEUE Q,int maxsize);void TraverseQueue(PQUEUE Q);bool FullQueue(PQUEUE Q);bool EmptyQueue(PQUEUE Q);bool Enqueue(PQUEUE Q, int val);bool Dequeue(PQUEUE Q, int *val);#endifqueue.c⽂件代码:#include<stdio.h>#include<stdlib.h>#include"malloc.h"#include"queue.h"/***********************************************Function: Create a empty stack;************************************************/void CreateQueue(PQUEUE Q,int maxsize){Q->pBase=(int *)malloc(sizeof(int)*maxsize);if(NULL==Q->pBase){printf("Memory allocation failure");exit(-1); //退出程序}Q->front=0; //初始化參数Q->rear=0;Q->maxsize=maxsize;}/***********************************************Function: Print the stack element;************************************************/void TraverseQueue(PQUEUE Q){int i=Q->front;printf("队中的元素是:\n");while(i%Q->maxsize!=Q->rear){printf("%d ",Q->pBase[i]);i++;}printf("\n");}bool FullQueue(PQUEUE Q){if(Q->front==(Q->rear+1)%Q->maxsize) //推断循环链表是否满,留⼀个预留空间不⽤ return true;elsereturn false;}bool EmptyQueue(PQUEUE Q){if(Q->front==Q->rear) //推断是否为空return true;elsereturn false;}bool Enqueue(PQUEUE Q, int val){if(FullQueue(Q))return false;else{Q->pBase[Q->rear]=val;Q->rear=(Q->rear+1)%Q->maxsize;return true;}}bool Dequeue(PQUEUE Q, int *val){if(EmptyQueue(Q)){return false;}else{*val=Q->pBase[Q->front];Q->front=(Q->front+1)%Q->maxsize;return true;}}。
循环队列的实现及细节
循环队列的实现及细节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 函数,否则⽣成的就是⼀个局部变量。
循环队列的基本操作及实现
循环队列的基本操作及实现循环队列是一种特殊的队列,它可以充分利用数组空间,实现队列的基本操作。
循环队列的基本操作包括入队、出队、判断队列是否为空、判断队列是否已满等。
1. 入队操作入队操作是将元素插入队列尾部的操作。
在循环队列中,需要考虑队列已满的情况。
当队列已满时,需要将队列头部的元素出队,然后再将新元素入队。
入队操作的代码如下:```void enqueue(int data) {if ((rear + 1) % MAX_SIZE == front) {dequeue();}queue[rear] = data;rear = (rear + 1) % MAX_SIZE;}```2. 出队操作出队操作是将队列头部的元素删除的操作。
在循环队列中,需要考虑队列为空的情况。
当队列为空时,无法进行出队操作。
出队操作的代码如下:```int dequeue() {if (front == rear) {return -1;}int data = queue[front];front = (front + 1) % MAX_SIZE;return data;}```3. 判断队列是否为空判断队列是否为空的操作是判断队列中是否还有元素的操作。
在循环队列中,队列为空的条件是队列头部和队列尾部相等。
判断队列是否为空的代码如下:```bool is_empty() {return front == rear;}```4. 判断队列是否已满判断队列是否已满的操作是判断队列中是否还有空间可以插入元素的操作。
在循环队列中,队列已满的条件是队列头部和队列尾部相邻。
判断队列是否已满的代码如下:```bool is_full() {return (rear + 1) % MAX_SIZE == front;}```循环队列的实现可以使用数组来实现,也可以使用链表来实现。
使用数组实现循环队列时,需要定义一个数组和两个指针,分别指向队列头部和队列尾部。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5、测试数据与实验结果(可以抓图粘贴)(1)菜单显示:
(2)入队:
(3)队满(已入队9个元素):
(4)出队:
(5)队空(已出队9个元素):
(6)显示队中的元素:
(7)求队长:
6、结果分析与实验体会
本次实验是参考了范例程序,经过自己的改写,从而实现要求。
先做简单的输出,一步步的再做其它格式的设置。
在实验的过程中,我加深了对队列各种操作的理解,因为队列是“先进先出”的操作受限制的线性表,一般队列只允许在队尾进行插入操作,在队头进行删除操作,元素之间存在一对一的关系,本程序的设计过程也是对前面线性表知识的巩固。
再者,用链式存储结构实现这个程序,实际上是设计一个带有头指针(front)和尾指针(rear)的单向链表,此单向链表没有头结点,头尾指针指的是同一个单向链表中的首尾结点,所以,从链队列的整体结构考虑,一般讲这两个指针封装在一个结构体中。
队列是一种应用广泛的数据结构,凡具有其特点的需要排队处理的问题,都可以使用它来处理。