顺序循环队列的基本操作

来源:互联网 发布:睿博数据 编辑:程序博客网 时间:2024/06/08 17:21

顺序循环队列是一种常见数据结构,所以今天我特地整理了一下,后面还会补上链表队列的实现,见我的博客数据结构栏目


1.先上几个头文件部分,里面是一些基本的定义

#include <iostream>//source.h#include <stdlib.h>using namespace std;
#define ERROR 0   //definition.h#define OK 1#define INIT_SIZE 100typedef int ElemType;typedef int Status;typedef struct queue{ElemType *base;//数组首地址int front,rear;//一个头下标,一个尾下标}Queue;
2.下面是各种基本操作了,我写在function.h里,由于比较简单,我就直接把他们放了上来,没有一个函数一个函数介绍

Status InitQueue(Queue &Q){Q.base = (ElemType *)malloc(INIT_SIZE*sizeof(ElemType));if (!Q.base){cout<<"内存分配失败"<<endl;return ERROR;}Q.rear = 0;Q.front = 0;return OK;}Status IsEmpty(Queue &Q){if (Q.front == Q.rear){cout<<"该队列为空"<<endl;return OK;}cout<<"该队列不为空"<<endl;return 0;}Status IsFull(Queue &Q){if ((Q.rear+1)%INIT_SIZE==Q.front)//此处判断队列是否满不能用isfull函数判断{cout<<"该队列已满"<<endl;return OK;}cout<<"该队列未满"<<endl;return 0;}Status EnQueue(Queue &Q,ElemType value){if ((Q.rear+1)%INIT_SIZE == Q.front){cout<<"该队列已满,不能再进入数据"<<endl;return ERROR;}Q.base[Q.rear] = value;cout<<Q.base[Q.front]<<endl;Q.rear = (Q.rear+1)%INIT_SIZE;return OK;}Status DeQueue(Queue &Q,ElemType &data){if (Q.front == Q.rear){cout<<"该队列为空!"<<endl;return ERROR;}data = Q.base[Q.front];cout<<"出队的值为:"<<data<<endl;Q.front = (Q.front+1)%INIT_SIZE;return OK;}Status GetHead(Queue &Q,ElemType &head){if (Q.front == Q.rear){cout<<"队列为空"<<endl;return ERROR;}head = Q.base[Q.front];return OK;}
3.下面是主函数部分,没什么亮点

#include "source.h"#include "definition.h"#include "function.h"void main(){int choice;ElemType value;ElemType head,data;Queue Q;Q.base = NULL;while (1){cout<<"顺序循环队列的基本操作"<<endl;cout<<"1.初始化队列"<<endl;cout<<"2.判断队列是否为空"<<endl;cout<<"3.判断队列是否满"<<endl;cout<<"4.元素入队"<<endl;cout<<"5.元素出队"<<endl;cout<<"6.获取头的值"<<endl;cout<<"0.退出程序"<<endl;cout<<"输入你的选择:"<<endl;cin>>choice;switch(choice){case 1:if (InitQueue(Q)){cout<<"初始化成功"<<endl;}break;case 2:IsEmpty(Q);break;case 3:IsFull(Q);break;case 4:cout<<"输入你要入队的值:"<<endl;cin>>value;EnQueue(Q,value);break;case 5:cout<<"正在执行。。。。。"<<endl;DeQueue(Q,data);break;case 6:GetHead(Q,head);cout<<"头的值为"<<head<<endl;break;case 0:exit(0);default:exit(0);}}system("pause");}
注意:虽然整个程序没什么亮点,但是还是有几点需要注意,那就是在写入队列函数也就是Enqueue()函数时,要判断队列是否满了,但是这里判断队列是否满了的代码是(Q.rear+1)%INIT_SIZE == Q.front,这里不能直接用前面写的IsFull()函数来作为条件,如果用isfull判断的话,会有一有关函数调用的问题,大家可以试一试,学习学习。

还有就是大家可能会疑问,判断队列满((Q.rear+1)%INIT_SIZE==Q.front)与判断队列空(Q.front==Q.rear)的条件。

大家都知道队列是尾进头出的结构,所以这就会导致尾部下标达到了最大值,实际上头部前面可能还有空间没有被使用,所以这就会达到所谓的假溢出状态,解决办法就是让下标达到了最大值过后,再让Q.rear的值重新回到0,也就是这段连续空间的最开始,这就形成了我们今天说的顺序循环队列,那么表满的条件是什么呢?你可能会认为是Q.rear==Q.front,但是Q.rear==Q.front也是队列为空的判断依据(如果按照这种方式判断的话,就会不准确),所以大佬们就想出了空出最后一个存储单元,来实现判断队列是否满了,那就是判断,(Q.rear+1)%INIT_SIZE==Q.front,这样就可以区分了。

附上一张图片:





每天进步一点点

原创粉丝点击