队列是一种先进先出的线性表,队尾入队存储,队头出队读取。普通队列在数据出队列后,使用过的地址空间依然没有被释放,产生了很大的浪费。环形队列可是使数据地址限定在某个范围内,重复使用。
实现一个环形队列,基本的功能有
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() const14 {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 else23 {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<