队列是一种操作受限的特殊线性表,插入只允许在队尾进行,删除只允许在队头进行。
队列的基本数据有队头指针、队尾指针、数据储存数组、最大长度
队列的基本操作有init(构造)、flush(销毁)、empty(判空)、full(判满)、push(数据插入队尾)、pop(删除队头数据)、clear(清空数据)、size(当前长度)、front(获取队头元素)
根据储存方式的不同,可以分为顺序队列和链式队列。
一、顺序队列
数据:队头、队尾指针,存储数组,最大容量
顺序队列就是使用顺序处存放室储存的队列,可以用结构体或者类来进行实现。
队头指针和队尾指针均使用整型序号实现,数据储存数组直接使用数组实现。
使用结构体构造顺序队列/循环队列
#include<iostream>
using namespace std;
//简单队列
struct cQueue
{
int *a;
int maxSize;
int front, rear;
};
void init(cQueue* q, int sz)
{
q->a = new int[sz];
q->maxSize = sz;
q->front = q->rear = 0;
}
void flush(cQueue* q)
{
delete q->a;
}
bool empty(cQueue* q)
{
return q->front == q->rear;
}
bool full(cQueue* q) // 循环队列 front = (rear + 1) % maxSize
{
return q->rear == q->maxSize;
}
void clear(cQueue* q)
{
q->front = q->rear = 0;
}
int size(cQueue* q) // 循环队列 (rear + maxSize - front) % maxSize
{
return q->rear - q->front;
}
bool push(cQueue* q, int x)
{
if(full(q)) return 0;
q->a[q->rear++] = x; //循环队列 rear = (rear+1) % maxSize;
return 1;
}
void pop(cQueue* q)
{
q->front++; //循环队列 front = (front+1) % maxSize;
}
int front(cQueue* q)
{
return q->a[q->front];
}
//测试队列
int main()
{
cQueue q;
init(&q, 100);
for(int i=1; i<=10; i++) push(&q, i);
cout<<size(&q)<<endl;
while(size(&q))
{
cout<<front(&q)<<" ";
pop(&q);
}
return 0;
}
使用类构造循环队列/顺序队列
#include<iostream>
using namespace std;
// 循环队列
class cQueue
{
int head, rear, maxSize;
int *a;
public:
cQueue(int sz);
~cQueue() {delete a;}
bool empty();
bool full();
int size();
int front();
void pop();//删除队头元素
void push(int x);
};
cQueue::cQueue(int sz)
{
head = rear = 0;
maxSize = sz;
a = new int[sz];
}
bool cQueue::empty()
{
return head == rear;
}
bool cQueue::full()
{
return head == (rear + 1) % maxSize; // 简单队列 rear == maxSize
}
int cQueue::size()
{
return (rear - head + maxSize) % maxSize; // 简单队列 return rear - front
}
void cQueue::push(int x)
{
a[rear++] = x;
rear %= maxSize; // 简单队列仅有第一行
}
int cQueue::front()
{
return a[head];
}
void cQueue::pop()
{
head++;
head %= maxSize; // 简单队列仅有第一行
}
//循环队列的正确性测试
int main()
{
cQueue q(100);
for(int i=1; i<=15; i++) // i<=15再测试一次
q.push(i);
while(q.size())
{
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
二、链式队列
节点数据:存储数据、向下指针
队列数据:队头、队尾指针,节点数量
链式队列清空数据就直接销毁节点了
#include<bits/stdc++.h>
using namespace std;
template <class T>
class cNode //单链表节点类.简单起见,成员均为public
{
public:
T data; //数据域
cNode<T> *next; //指向下一个结点
cNode(const T& item)
{
data = item; next = NULL;
}
~cNode() { }
};
template<class T>
class cQueue
{
cNode<T> * head, rear;
int count;
public:
cQueue()
{
head = rear = NULL;
count = 0;
}
~cQueue()
{
clear();
}
bool empty()
{
return head == NULL && rear == NULL;
}
void push(T x)
{
cNode<T> * p = new cNode<T>(x);
p->next = head;
head = p;
count++;
}
void pop()
{
cNode<T> * p = head;
while(p->next != NULL)
{
p = p->m_next;
}
rear = p;
delete p->next;
p->next = NULL;
count--;
}
void clear()
{
while(count)
{
cNode<T> * p = head;
head = head->next;
delete p;
count--;
}
}
};
三、C++自带队列类
需要引入头文件
#include<queue>
定义队列类对象,以储存int为例
queue<int> q;
队列类自带的方法,其中T为储存的数据类型
bool empty(); // 如果队列为空返回1,否则返回0
int size(); // 返回当前队列中元素的个数
void pop(); // 删除队头元素,无返回值
void push(T x); // 队尾添加元素x,无返回值
T front(); // 返回队头元素
T back(); // 返回队尾元素