循環隊列/順序隊列(C++)


隊列(queue)是一種限定存取位置的線性變。他允許在表的一端插入,在另一端刪除。這個和計算機調度策略中的先來先服務FCFS(First Come/First Served)是一樣的。隊列中可以插入的一端為隊尾(rear),允許刪除的一端稱為隊頭(front)。

隊列也分為兩種,一種是用數組的存儲表示,一種是基於鏈表的存儲表示。

基於數組的存儲表示的隊列被稱為順序隊列。其數據成員包括,一維數組elements用來存儲數據,指針front和rear用來指示隊尾隊頭的位置,maxSize是數組的最大長度。

 

 從上邊的圖可以看出來,rear指針到指到數組最后一位時就不能繼續往后添加元素,如果之前刪除過元素,front指針前還有空閑的空間未被使用,造成空間的浪費。所以,使隊列循環起來就可以使其最大限度的利用空間。

變成循環隊列,為了避免越界,每次添加新元素時,尾指針需要加一后對堆長取余

rear = (rear+1)%maxSize;

刪除元素也一樣

front = (front+1)%maxSize;

為了區別於空隊列,用(rear+1)%maxSize==front來判斷是否隊滿,即隊尾走到隊頭前一個位置即判定隊滿。再因為隊尾所指的空間為最后一個元素的下一個位置,所以循環隊列最多能存放maxSize-1個元素

//queue.h
#ifndef _QUEUE_H
#define _QUEUE_H
#include<iostream>
using namespace std;
const int maxSize = 50;
template<class T>
class Queue
{
public:
	Queue(){};
	~Queue(){};
	virtual bool EnQueue(const T& x) = 0;
	virtual bool DeQueue(T& x) = 0;
	virtual bool getFront(T& x) = 0;
	virtual bool IsEmpty()const = 0;
	virtual bool IsFull()const = 0;
	virtual int getSize()const = 0;
};
#endif

 

//main.cpp
#include<assert.h> #include"queue.h" template<class T> class SeqQueue; template<class T> ostream& operator<< (ostream& out, SeqQueue<T>& Q)//將友元函數聲明在前可以避免其警告友元函數未聲明 { cout<<"front = "<<Q.front<<", rear = "<<Q.rear<<endl; if(!Q.IsEmpty()) { int i = Q.front; while(i!=Q.rear) { cout<<Q.elements[i]<<" | "; i = (++i)%maxSize; } } return out; } template<class T> class SeqQueue: public Queue<T> { private: int rear, front; T *elements; int maxSize; public: SeqQueue(int sz=10);//構造函數 ~SeqQueue(){delete[] elements;}//析構函數 bool EnQueue(const T& x);//入隊列 bool DeQueue(T& x);//出隊列 bool getFront(T& x);//找隊頭 bool IsEmpty()const{return (this->rear==this->front) ? true : false;}//判空 bool IsFull()const{return ((this->rear+1)%this->maxSize==this->front) ? true : false;}//判滿 int getSize()const{return(this->rear-this->front+this->maxSize)%this->maxSize;}//得隊長 friend ostream& operator<<<>(ostream& out, SeqQueue<T>& Q); //void print(); }; /*template<class T> void SeqQueue<T>::print() { if(!this->IsEmpty()) { int i = this->front; while(i!=this->rear) { cout<<this->elements[i]<<" | "; i = (++i)/this->maxSize; } } }*/ template<class T> bool SeqQueue<T>::EnQueue(const T& x) { if(!this->IsFull()) { this->elements[this->rear] = x; this->rear = (this->rear+1)%this->maxSize; return true; } return false; } template<class T> bool SeqQueue<T>::DeQueue(T& x) { if(!this->IsEmpty()) { x = this->elements[this->front]; this->front = (this->front+1)%this->maxSize; return true; } return false; } template<class T> bool SeqQueue<T>::getFront(T& x) { if(!this->IsEmpty()) { x = this->elements[this->front]; return true; } return false; } template<class T> SeqQueue<T>::SeqQueue(int sz):front(0),rear(0),maxSize(sz) { this->elements = new T[maxSize]; assert(this->elements!=NULL); } int main() { SeqQueue<int> Q(7); for(int i=7; i>0; --i) Q.EnQueue(i); cout<<Q<<endl;//聲明友元函數並重載輸出運算符<<就可以用cout直接輸出對象 int q = 0; for(int i=3; i>=0; --i) Q.DeQueue(q); cout<<Q<<endl; cout<<"Size = "<<Q.getSize()<<endl; return 0; }

 

運行結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM