循环队列原理
当我们使用队列出队是,采用首指针加一的方式会导致队列的存储空间变小,甚至出现首指针和尾指针同时指向尾节点的“假溢出”问题,所以出现了循环队列。
循环队列也是一种顺序存储的线性表,我们的队列长度会比普通的队列长度少一,比如定位为长度是5的循环队列,实际只能存储4个元素。
结构体定义:
这里使用的是顺序存储,设立一个队首指针 front ,一个队尾指针 rear,分别指向队首和队尾元素。
typedef struct Queue
{
int data[MAX];
int front;
int rear;
}Queue;
队列代码实现
遍历
遍历十分简单,因为是顺序存储,所以可以直接使用下标访问。
不同的是当尾指针在首指针前面的情况,所以使用了i%MAX!= q->rear的条件。
void printQueue(Queue* q)
{
if (!q) return;
for (int i = q->front; i % MAX != q->rear; i++)
{
cout << q->data[i] << " ";
}
cout << endl;
}
}
入队
队列的入队是将数据插入到队列的尾部
这里的可以q->rear = (q->rear + 1) % MAX;实现将尾指针放在首指针前面,从而实现循环。
bool enterQueue(Queue* q, int val)
{
if (!q) return false;
if (isFulll(q))
{
cout << "队列已满" << endl;
return false;
}
q->data[q->rear] = val;
q->rear = (q->rear + 1) % MAX;
return true;
}
出队
循环队列的出队使用的是对首指针的操作,避免了移动元素,效率更高。
bool deleteQueue(Queue* q, int & node)
{
if (!q) return false;
if (isEmpty(q))
{
cout << "队列为空" << endl;
return false;
}
node = q->data[q->front];
q->front = (q->front + 1) % MAX;
return true;
}
取首元素
int getHead(Queue * q)
{
if (!q || isEmpty(q)) return 0;
return q->data[q->front];
}
完整代码
#include <iostream>
using namespace std;
#define MAX 5 //队列长度
typedef struct Queue
{
int data[MAX];
int front;
int rear;
}Queue;
//初始化
bool initQueue(Queue* q)
{
if (!q) return false;
q->front = q->rear = 0;
return true;
}
//遍历
void printQueue(Queue* q)
{
if (!q) return;
for (int i = q->front; i % MAX != q->rear; i++)
{
cout << q->data[i] << " ";
}
cout << endl;
}
//判断队列为空
bool isEmpty(Queue* q)
{
if (!q) return false;
if (q->rear == q->front)
{
return true;
}
return false;
}
//判断队列满
bool isFulll(Queue* q)
{
if (!q) return false;
if ((q->rear + 1) % MAX == q->front)
{
return true;
}
return false;
}
//入队
bool enterQueue(Queue* q, int val)
{
if (!q) return false;
if (isFulll(q))
{
cout << "队列已满" << endl;
return false;
}
q->data[q->rear] = val;
q->rear = (q->rear + 1) % MAX;
return true;
}
//出队
bool deleteQueue(Queue* q, int & node)
{
if (!q) return false;
if (isEmpty(q))
{
cout << "队列为空" << endl;
return false;
}
node = q->data[q->front];
q->front = (q->front + 1) % MAX;
return true;
}
//取首元素
int getHead(Queue * q)
{
if (!q || isEmpty(q)) return 0;
return q->data[q->front];
}
int main(void)
{
Queue* q = new Queue;
initQueue(q);
cout << "插入5 10 15 20 25 30(队列长度为5)" << endl;
for (int i = 1; i < 7; i++)
{
enterQueue(q, i * 5);
}
printQueue(q);
cout << "队列首元素为:" << getHead(q) << endl;
int node = 0;
cout << "出队后" << endl;
deleteQueue(q, node);
cout << "出队的元素是:" << node << endl;
printQueue(q);
delete q;
return 0;
}