和棧相反,隊列是FIFO表,先進先出。故名思議,和排隊打飯一樣,先入隊的先打完出去,而且只能從隊列的尾端加入(插隊的滾粗啊。。)。用數組實現隊列的話,循環隊列是一般是必須的。我們會用2個下標head and tail來標記隊頭和隊尾的位置,如果有人出隊的話,head就會+1,入隊tail+1,這樣整個隊列在數組中的位置就會慢慢向右移動,不做處理的話很快會到達數組的尾端。因此,循環隊列的采取這樣的操作,當隊頭或者隊尾超出存儲隊列的預設長度的話,就把他們置為0,等於再從數組的左邊開始向右增長,形成“卷繞”。
開始時,我們把head和tail初始化為0,這時的隊列是空的,此后我們也可以用head == tail 這條語句來判斷一個隊列是否為空。
NOTE:采用這種判斷條件的話,對於規模為N的數組來說只能規模為N - 1的隊列,因為如果此時再入隊一個對象,tail == head就成立了,意味着隊列為空,這不符合邏輯。
判斷隊列滿有兩種情況:
1. 此時head為0,tail = length - 1,意味着已經有N - 1個對象在隊列里。
2. head大於0,則隊列滿的條件為head = tail + 1,這種情況畫個圖就明白了,是由於“卷繞”造成的。
這是算法導論上的示意圖。下面貼下我簡單實現的代碼,C++寫的模板類
#ifndef _QUEUE_H_
#define _QUEUE_H_
template <class T>
class Queue
{
private:
int head;
int tail;
int length;
T* array;
public:
Queue(){tail = head = length = 0;}
Queue(int size);
~Queue();
bool isEmpty();
bool isFull();
void enQueue(T val);
T deQueue();
};
template <class T>
Queue<T>::Queue(int size)
{
tail = head = 0;
length = size;
array = new T[size];
}
template <class T>
Queue<T>::~Queue()
{
delete [] array;
}
template <class T>
bool Queue<T>::isEmpty()
{
return head == tail;
}
template <class T>
bool Queue<T>::isFull()
{
return (head == tail + 1) || (tail - head == length - 1);
}
template <class T>
void Queue<T>::enQueue(T val)
{
if(isFull())
{
std::cout << "Queue overflow!" << std::endl;
/*
exit or someting else
*/
}
else
{
array[tail++] = val;
if(tail == length)
tail = 0;
}
}
template <class T>
T Queue<T>::deQueue()
{
T ret;
if(isEmpty())
{
std::cout << "Queue is empty!" << std::endl;
/*
exit or someting else
*/
}
else
{
ret = array[head++];
if(head == length)
head = 0;
return ret;
}
}
#endif
兩種最基本的線性表寫完了,過幾天回家寫個鏈表![]()
