2.10.2 顺序循环队列
顺序队列中当元素删除时,删除的元素处被置为0,但是空间实际上还在,当元素存放满时,由于删除只是置0,所以导致队首下标front后移,所以导致了之前被删除的元素造成空间浪费,存满后形成假溢出无法插入元素(实际上前边被“删除”的元素空间还在,只是值为0),所以为了节省空间,使用顺序循环队列,保证可以在插入元素放满之后(假溢出)还可以利用有效空间插入元素。随着删除和插入的动作较多时,新元素会顶替老元素的位置继续存储从而实现循环存储。
-
代码:
seqloopqueque.h
#ifndef SEQLOOPQUEUE_H #define SEQLOOPQUEUE_H #define SEQLOOPQUEUESIZE 5 #include <iostream> using namespace std; class SeqLoopQueue { public: SeqLoopQueue(); bool isEmpty(); bool enterQueue(char ch);//插入只能从队尾插入 int deleteItem();//删除只能从队首删除 const char getHeadItem()const;//得到头位置元素 void clearQueue(); void prtAllItems(); private: char loopQueue[SEQLOOPQUEUESIZE];//字符数组 int head;//队列首元素下标 int tail;//队列尾元素下标 int flag;//标志位,为0代表队列删除了元素,为1代表队列添加了元素 }; #endif // SEQLOOPQUEUE_H
seqloopqueue.cpp
#include "seqloopqueue.h" #include <memory.h> SeqLoopQueue::SeqLoopQueue() { this->head = 0; this->tail = 0; this->flag = 0; memset(loopQueue,0,SEQLOOPQUEUESIZE); } //判断队列为空的逻辑:首尾下标相等且flag==0 bool SeqLoopQueue::isEmpty() { if(this->head==this->tail && this->flag==0)//flag==1代表队列中删除入了元素,队列不可能为满 { return true; } return false; } bool SeqLoopQueue::enterQueue(char ch) { if(this->tail>=SEQLOOPQUEUESIZE) this->tail=0;//当尾位置到达数组最大长度时,将tail置为0,形成闭环 if(this->head==this->tail && this->flag==1){//flag==1代表队列中插入了元素,队列不可能为空 //判断队列满的逻辑:由于是循环队列,当元素满时,tail要设为0,再从数组(loopQueue)的起始处开始插入,当队尾和队首相等时记为队列满。 cout<<"the queue is fill , don't push item!"<<endl; return false; } else { this->loopQueue[tail++] = ch; this->flag = 1; return true; } } int SeqLoopQueue::deleteItem() { if(this->head>=SEQLOOPQUEUESIZE) this->head = 0; if(isEmpty()) { cout<<"the queue is empty, don't delete!"<<endl; return false; } else { char temp = loopQueue[head]; loopQueue[this->head++] = 0;//删除位置置0 this->flag = 0;//表示删除了元素,即队列不可能满 return temp;//返回删除的元素 } } const char SeqLoopQueue::getHeadItem() const { return loopQueue[this->head];//这里需要判空,但是我这里元素都是0,所以没做,因为删除后都会把元素置为0且初始化也将元素都只为0了,所以不判断了。 //即,如果为空了,则返回空字符。 } void SeqLoopQueue::clearQueue() { this->head = 0; this->tail = 0; this->flag = 0; } void SeqLoopQueue::prtAllItems() { for (int i = 0;i<SEQLOOPQUEUESIZE;++i) { cout<<loopQueue[i]; } cout<<endl; }
main.cpp
#include <iostream> #include "seqloopqueue.h" using namespace std; int main() { SeqLoopQueue scq; scq.enterQueue('1'); scq.enterQueue('2'); scq.enterQueue('3'); scq.enterQueue('4'); scq.enterQueue('5'); scq.enterQueue('8');//the queue is fill , don't push item! cout<<scq.getHeadItem()<<endl;//1 scq.deleteItem(); cout<<scq.getHeadItem()<<endl;//2 scq.enterQueue('6'); scq.prtAllItems();//62345 scq.enterQueue('7');//the queue is fill , don't push item! scq.prtAllItems();//62345 cout<<scq.getHeadItem()<<endl;//2 return 0; }