队列大家见得很多了,形式也比较简单,就是一个特化的链表,它的enqueue、dequeue操作相当于链表的addLast、removeFirst操作。关于链表的实现,可以查看我的另一篇博文--"LinkedList--链表"。下面仅讨论一个稍微复杂点的情况--循环队列。
循环队列的就是用循环数组来实现队列,有一个问题需要解决:在普通的非循环队列中,rear == front 说明队列为空队列,然而在循环队列中,这个可能意味着队列为空,也可能意味着队列为满。通常采用两种策略来处理这个问题。
1. 设置一个标识位,以区别队列是空还是满。可以这样认为:初始化的时候令 front = rear = 0,flag = 0代表空。通过enqueue 入队操作使得 front = rear,认为到达满状态,flag = 1;通过dequeue 出队操作使得 front = rear,认为到达空状态,flag = 0。
2. 少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(循环状态的下一位置)”作为判定队列满的标识。
策略1代码如下所示:
#ifndef _CIRQUEUE_H #define _CIRQUEUE_H #include <iostream> #include <stdexcept> using namespace std; //MAXN个空间, 所有空间都可用 const int MAXN = 5; template<typename T> class cirQueue { private: bool isEmpty; T array[MAXN]; int front,rear; public: cirQueue(); cirQueue(T *list,int SIZE); void enque(T e); T deque(); int getSize(); void print(); }; template<typename T> cirQueue<T>::cirQueue() { front = rear = 0; isEmpty = 1; } template<typename T> cirQueue<T>::cirQueue(T *list , int SIZE) { front = rear = 0; isEmpty = 1; if(SIZE > MAXN || SIZE < 0) throw runtime_error("Index out of range"); for(int i = 0 ; i < SIZE ; i ++) enque(list[i]); } template<typename T> //若队列非满,增加队尾元素 void cirQueue<T>::enque(T e) { if(rear == front && !isEmpty) { cout << "Already full !\n"; return; } array[rear] = e; rear = (rear+1)%MAXN; if(rear == front) isEmpty = 0; } template<typename T> //若队列非空,删除队头元素 T cirQueue<T>::deque() { if(rear == front && isEmpty) { throw runtime_error("Already empty !\n"); } T ele = array[front]; front = (front+1)%MAXN; if(rear == front) isEmpty = 1; return ele; } template<typename T> int cirQueue<T>::getSize() { if(rear == front) return (isEmpty ? 0 : MAXN); else return (rear-front+MAXN) % MAXN; } template<typename T> void cirQueue<T>::print() { int cnt = getSize(); if(cnt == 0) { cout << "Empty Queue !\n"; return; } int i=0,inde = front; while(i < cnt) { cout << array[inde] << " "; inde = (inde+1)%MAXN; i ++; } cout << endl; } #endif
策略2代码如下所示:
#ifndef _CIRQUEUE_H #define _CIRQUEUE_H #include <iostream> #include <stdexcept> using namespace std; //101个空间,有一个空间不可用 const int MAXN = 101; template<typename T> class cirQueue { private: T array[MAXN]; int front,rear; public: cirQueue(); cirQueue(T *list,int SIZE); void enque(T e); T deque(); int getSize(); }; template<typename T> cirQueue<T>::cirQueue() { front = rear = 0; } template<typename T> cirQueue<T>::cirQueue(T *list , int SIZE) { front = rear = 0; if(SIZE >= MAXN-1) throw runtime_error("Index out of range"); for(int i = 0 ; i < SIZE ; i ++) enque(list[i]); } template<typename T> //若队列非满,增加队尾元素 void cirQueue<T>::enque(T e) { if((rear+1)%MAXN == front) { cout << "Already full !\n"; return; } array[rear] = e; rear = (rear+1)%MAXN; } template<typename T> //若队列非空,删除队头元素 T cirQueue<T>::deque() { if(rear == front) { throw runtime_error("Already empty !\n"); } T ele = array[front]; front = (front+1)%MAXN; return ele; } template<typename T> int cirQueue<T>::getSize() { return (rear-front+MAXN) % MAXN; } #endif
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-13 23:38:27