一. 队列(Queue)
队列(queue) 和堆栈相似,是一种可以存取的数据结构,不同的是队列的存取是在两个不同的方向进行的,因此其主要特征是先进先出(First-in-first-out,FIFO)
头指针(front) 指向队列的第一个位置,数据的输出端
尾指针(rear) 指向队列的最后一个位置,数据的进入端
队列也可分为静态队列(Static Queue)和动态队列(Dynamic Queue)两类:
- Static Queue: 队列的大小固定,可以用数组实现;
- Dynamic Queue: 队列的大小随需要改变,可以用链表实现
二. 基本操作(Basic Operation)
- 入队(Enqueue):Insert an element at the rear of the queue
- 出队(Dequeue):Remove an element from the front of the queue
按照如图所示的方式进行入队和出队,每当一个元素进入或移出时,所有的元素都要进行一次移位,这样的操作效率极低,因此改用如下移动指针的方式可以提高效率:
- 利用环形数组实现,OOOOO7963 →4OOOO7963 ((4)入队后的变化)
- 当有元素入队时,尾指针向前移动
- 当有元素出队时,头指针向队列后面移动一个元素(这样就删除了前面的元素,所以不需要复制到相邻的元素)。
这里存在的问题是后指针不能移到数组中最后一个元素之外。
例:
三. C++ 代码
- 静态队列(Static Queue):
#include <iostream>
using namespace std;
class Queue
{
public:
Queue(int size);// constructor
~Queue();// destructor
bool IsEmpty(void);
bool IsFull(void);
bool Enqueue(double x);
bool Dequeue(double &x);
void DisplayQueue(void);
private:
int front;// front index
int rear;// rear index
int counter;// number of elements
int maxSize;// size of array queue
double* values;// element array
};
Queue::Queue(int size)
{
values = new double[size];
maxSize = size;
front = 0;
rear = -1;
counter = 0;
}
Queue::~Queue()
{
delete [] values;
}
bool Queue::IsEmpty()
{
if (counter)
return false;
else
return true;
}
bool Queue::IsFull()
{
if (counter < maxSize)
return false;
else
return true;
}
bool Queue::Enqueue(double x)
{
if (IsFull())
{
cout<< "Error: the queue is full." << endl;
return false;
}
else
{
// calculate the new rear position (circular)
rear= (rear + 1) % maxSize;
// insert new item
values[rear]= x;
// update counter
counter++;
return true;
}
}
bool Queue::Dequeue(double &x)
{
if (IsEmpty())
{
cout<< "Error: the queue is empty." << endl;
return false;
}
else
{
// retrieve the front item
x= values[front];
// move front
front= (front + 1) % maxSize;
// update counter
counter--;
return true;
}
}
void Queue::DisplayQueue()
{
cout<< "front -->";
for (int i = 0; i < counter; i++)
{
if (i == 0)
cout << "\t";
else
cout << "\t\t";
cout<< values[(front + i) % maxSize];
if (i != counter - 1)
cout << endl;
else
cout << "\t<--rear" << endl;
}
}
int main(void)
{
Queue queue(5);
cout<< "Enqueue 5 items." << endl;
for (int x = 0; x < 5; x++)
queue.Enqueue(x);
cout<< "Now attempting to enqueue again..." << endl;
queue.Enqueue(5);
queue.DisplayQueue();
double value;
queue.Dequeue(value);
cout<< "Retrieved element = " << value << endl;
queue.DisplayQueue();
queue.Enqueue(7);
queue.DisplayQueue();
return 0;
}
- 动态队列(Dynamic Queue):
#include <iostream>
using namespace std;
class Node {
public:
double data; // data
Node* next; // pointer to next
};
class Queue
{
public:
Queue();// constructor
~Queue();// destructor
bool IsEmpty(void);
void Enqueue(double x);
bool Dequeue(double &x);
void DisplayQueue(void);
private:
Node* front;// front index
Node* rear;// rear index
int counter;// number of elements
};
Queue::Queue()
{
front = rear = NULL;
counter = 0;
}
Queue::~Queue()
{
double value;
while (!IsEmpty())
Dequeue(value);
}
bool Queue::IsEmpty()
{
if (counter)
return false;
else
return true;
}
void Queue::Enqueue(double x)
{
Node* newNode = new Node;
newNode->data = x;
newNode->next = NULL;
if (IsEmpty())
{
front = newNode;
rear = newNode;
}
else
{
rear->next = newNode;
rear = newNode;
}
counter++;
}
bool Queue::Dequeue(double &x)
{
if (IsEmpty())
{
cout<< "Error: the queue is empty." << endl;
return false;
}
else
{
x= front->data;
Node* nextNode = front->next;
delete front;
front = nextNode;
counter--;
}
}
void Queue::DisplayQueue()
{
cout<< "front -->";
Node* currNode = front;
for (int i = 0; i < counter; i++)
{
if (i == 0)
cout << "\t";
else
cout << "\t\t";
cout << currNode->data;
if (i != counter - 1)
cout << endl;
else
cout << "\t<--rear" << endl;
currNode=currNode->next;
}
}
int main(void)
{
Queue queue;
cout<< "Enqueue 5 items." << endl;
for (int x = 0; x < 5; x++)
queue.Enqueue(x);
cout<< "Now attempting to enqueue again..." << endl;
queue.Enqueue(5);
queue.DisplayQueue();
double value;
queue.Dequeue(value);
cout<< "Retrieved element = " << value << endl;
queue.DisplayQueue();
queue.Enqueue(7);
queue.DisplayQueue();
return 0;
}