队列简单介绍
队列和栈是常用的两种结构,栈的特点是后进先出,队列特点则是先进先出,可以将队列看作是“排队”的模式;
并且队列的出入特点:
1. 只能从队头删除
2. 只能从队尾添加
队列相应的一些操作:
链式队列
队头:添加不变,删除变
队尾:指向nullptr,反
某些抽象Operation:
InitQueue(); 初始化
DestroyQueue(); 若Q存在,则销毁
ClearQueue(); 若存在且非空,则清空
QueueEmpty(); 若非空,返回true ,否则false
GetHead(); 若非空,返回队头
EnQueue(e); 若Q存在,添加结点e;
DeQueue(); 若Q非空,删除队头元素;
QueueLength(); 返回队列元素个数
后面介绍简单的几个操作,添加和删除;
结点的结构
template <class T>
struct Node {
T data;
Node* next;
};
构造队列
和栈不同,队列有俩指针,一个指向队头front,一个指向队尾rear
struct LinkQueue {
Node* front, * rear;
LinkQueue() :front(nullptr), rear(nullptr) {}
void InitLinkQ();
void LQ_push(string);
void LQ_pop();
void LQ_show();
int QueueLength();
};
功能完善:
//初始化队列
void LinkQueue::InitLinkQ() { //初始化时首尾指向同一结点
front = new Node();
rear = front;
rear->next = nullptr;
}
//添加结点
void LinkQueue::LQ_push(string s) { //每次添加队尾更新
//ready space
Node* p = new Node();
p->data = s; //make up rear
p->next = nullptr;
rear->next = p; //update rear
rear = p;
}
//删除结点
void LinkQueue::LQ_pop() {
Node* p = front->next;
delete front;
front = p; //更新队头
}
void LinkQueue::LQ_show() {
Node* p = front->next;
while (p) { //front 不存数据,而rear 存数据
cout << p->data << endl;
p = p->next;
}
}
int LinkQueue::QueueLength() {
int ret(0);
Node* p = front->next;
while (p) {
ret++;
p = p->next;
}
return ret;
}
循环队列
struct Queue {
string* data;
int front;
int rear;
Queue() :front(0), rear(0), data(nullptr) {}
void InitQueue();
void Push(string s);
void Pop();
void Show();
int GetLength();
};
void Queue::InitQueue() {
data = new string[MAX_SIZE];
front = 0;
rear = 0;
}
void Queue::Push(string s) { //添加:判断是否队满----队头不变,队尾+1
if ((rear + 1) % MAX_SIZE != front) {
data[rear] = s;
rear = (rear + 1) % MAX_SIZE;
}
}
void Queue::Pop() { //删除:判断队列是否为空----队头+1,队尾不变
if (front == rear) return;
front = (front + 1) % MAX_SIZE;
}
void Queue::Show() {
int p = front;
int q = rear;
while ((MAX_SIZE + q - p) % MAX_SIZE) { //数组有效长度=MAX_SIZE - p + q (p > q)
cout << data[p] << endl; //数组有效长度=q - p (p < q)
p = (p + 1) % MAX_SIZE;
}
}
int Queue::GetLength() {
int p = front;
int q = rear;
int ret(0);
while ((MAX_SIZE + q - p) % MAX_SIZE)
{
++ret;
p = (p + 1) % MAX_SIZE;
}
return ret;
}
在循环队列中,需要注意的主要就是“循环时坐标的变换”,
1.当队满时:
(rear + 1) % MAX_SIZE == front;
2.当队空时:
rear == front;
3.队头,队尾的“下标”变化
front =(front+1)%MAX_SIZE
rear = (rear+1)%MAX_SIZE
其它按照正常写即可;