队列是一种先进先出的线性表,队尾入队存储,队头出队读取。普通队列在数据出队列后,使用过的地址空间依然没有被释放,产生了很大的浪费。环形队列可是使数据地址限定在某个范围内,重复使用。
实现一个环形队列,基本的功能有
1 #ifndef MyQueue_h 2 #define MyQueue_h 3 4 class MyQueue 5 { 6 public: 7 MyQueue(int queueCapacity); //创建队列 8 ~MyQueue(); //销毁队列 9 void ClearQueue(); //清空队列 10 bool QueueFull() const; //队列判满 11 bool QueueEmpty() const; //队列判空 12 int QueueLength(); //队列长度 13 bool EnQueue(int element); //新元素入队 14 bool DeQueue(int &element); //首元素出队 15 void QueueTraverse(); //遍历队列 16 private: 17 int *_pQueue; //队列指针 18 int _iQueueLen; //队列长度 19 int _iQueueCapacity; //队列容量 20 int _iHead; //队列头 21 int _iTail; //队列尾 22 } 23 24 #endif /* MyQueue_h */
构造函数和析构函数实现创建、销毁队列并确定队列容量
1 MyQueue::MyQueue(int queueCapacity) 2 { 3 _iQueueCapacity=queueCapacity; 4 _pQueue=new int[_iQueueCapacity]; 5 ClearQueue(); 6 } 7 8 MyQueue::~MyQueue() 9 { 10 delete[] _pQueue; 11 _pQueue=NULL; 12 }
创建队列时应该队头,队尾和队列长度都置为零,所以直接使用了作用相同的清空队列函数
1 void MyQueue::ClearQueue() 2 { 3 _iHead=0; 4 _iTail=0; 5 _iQueueLen=0; 6 }
队列判空和判满用于判断是否能读取和插入数据
1 bool MyQueue::QueueFull() const 2 { 3 if(_iQueueLen==_iQueueCapacity) 4 { 5 return true; 6 } 7 else 8 { 9 return false; 10 } 11 } 12 13 bool MyQueue::QueueEmpty() const 14 { 15 if(_iQueueLen==0) 16 { 17 return true; 18 } 19 else{ 20 return false; 21 } 22 }
在定义队列类时,队列长度写为了私有类型,所以如果有需要,则须用公有类型的QueueLength()函数得到
1 int MyQueue::QueueLength() 2 { 3 return _iQueueLen; 4 }
环形队列中,存和取类似,需要注意的是环形问题,比如当队头的位置大于队列容量时,需要通过对队列容量取余得到正确的队头地址,队尾类似。同时伴随队列长度的加减。
1 bool MyQueue::EnQueue(int element) 2 { 3 if(QueueFull()) 4 { 5 return false; 6 } 7 else 8 { 9 _pQueue[_iTail]=element; 10 _iTail=++_iTail%_iQueueCapacity; 11 _iQueueLen++; 12 return true; 13 } 14 } 15 16 bool MyQueue::DeQueue(int &element) 17 { 18 if(QueueEmpty()) 19 { 20 return false; 21 } 22 else 23 { 24 element=_pQueue[_iHead]; 25 _iHead=++_iHead%_iQueueCapacity; 26 _iQueueLen--; 27 return true; 28 } 29 }
遍历队列时,可以用for循环从头依次输出,注意定义循环变量i时,i的起始在队头,循环次数为队列长度,所以终止在队列长度+队头。输出时的地址也应该如存取时一样,用循环变量对队列容量取余得到正确的地址。
1 void MyQueue::QueueTraverse() 2 { 3 using namespace std; 4 5 cout<<endl; 6 for(int i=_iHead;i<_iQueueLen+_iHead;i++) 7 { 8 cout<<_pQueue[i%_iQueueCapacity]<<endl; 9 } 10 cout<<endl; 11 }