一、循环队列
1.结构体的定义
typedef struct CircleIntQueue
{
int data[TOTAL_SPACE];
int head;
int tail;
}*CircleIntQueuePtr;
2.初始化
CircleIntQueuePtr initQueue()
{
CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(CircleIntQueue));
resultPtr->head = 0;
resultPtr->tail = 0;
return resultPtr;
}
3.判断队满
bool IsFull(CircleIntQueuePtr paraPtr)
{
if ((paraPtr->tail + 1) % MaxSize == paraPtr->head)
return true;
else
return false;
队满: (paraPtr->tail + 1) % MaxSize == paraPtr->head
尾指针像后移动一位,遇到头指针了。
4.判断队空
//判断队列为空
int IsEmpty(CircleIntQueuePtr paraPtr)
{
if (!paraPtr)
return 0;
if (paraPtr->head == paraPtr->tail)
return 1;
else
return 0;
}
5.入队(略有改动)
void EnterQueue(CircleIntQueuePtr paraPtr, int paraValue)
{
if (IsFull(paraPtr))
{
cout << "Queue full." << endl;
return;
}
paraPtr->data[paraPtr->tail] = paraValue;
paraPtr->tail = (paraPtr->tail+1)% MaxSize;
}
1.这里有些许改动,队入队后,队尾指针的处理有改动。
2.在上一次所讲到队列的顺序存储中,出队有两种方式,法二可以避免移动,但是可能会造成“假溢出”现象。但是循环队列却可以有效解决这个问题。
6.出队(略有改动)
int DeleteQueue(CircleIntQueuePtr paraPtr)
{
int resultValue;
if (paraPtr->head == paraPtr->tail) {
cout << "No element in the queue." << endl;
return -1;
}
resultValue = paraPtr->data[paraPtr->head];
paraPtr->head = (paraPtr->head+1) % MaxSize;
return resultValue;
}
出队后,注意队首指针的处理。
7.打印循环队列
void outputLinkQueue(CircleIntQueuePtr paraPtr) {
if (IsEmpty(paraPtr))
{
cout << "Empty queue." << endl;
return;
}
cout << "Elements in the queue: " << endl;
int i = paraPtr->head;
while (i != paraPtr->tail)
{
cout << " " << paraPtr->data[i];
i = (i + 1) % MaxSize;
}
cout << endl;
}
8.完整代码
#include <iostream>
using namespace std;
#define MaxSize 5
typedef struct CircleIntQueue
{
int data[MaxSize];
int head;
int tail;
}*CircleIntQueuePtr;
CircleIntQueuePtr initQueue()
{
CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(CircleIntQueue));
resultPtr->head = 0;
resultPtr->tail = 0;
return resultPtr;
}
bool IsFull(CircleIntQueuePtr paraPtr)
{
if ((paraPtr->tail + 1) % MaxSize == paraPtr->head)
return true;
else
return false;
}
//判断队列为空
int IsEmpty(CircleIntQueuePtr paraPtr)
{
if (!paraPtr)
return 0;
if (paraPtr->head == paraPtr->tail)
return 1;
else
return 0;
}
void EnterQueue(CircleIntQueuePtr paraPtr, int paraValue)
{
if (IsFull(paraPtr))
{
cout << "Queue full." << endl;
return;
}
paraPtr->data[paraPtr->tail] = paraValue;
paraPtr->tail = (paraPtr->tail+1)% MaxSize;
}
int DeleteQueue(CircleIntQueuePtr paraPtr)
{
int resultValue;
if (IsEmpty(paraPtr))
{
cout << "No element in the queue." << endl;
return -1;
}
resultValue = paraPtr->data[paraPtr->head];
paraPtr->head = (paraPtr->head + 1) % MaxSize;
return resultValue;
}
void outputLinkQueue(CircleIntQueuePtr paraPtr) {
if (IsEmpty(paraPtr))
{
cout << "Empty queue." << endl;
return;
}
cout << "Elements in the queue: " << endl;
int i = paraPtr->head;
while (i != paraPtr->tail)
{
cout << " " << paraPtr->data[i];
i = (i + 1) % MaxSize;
}
cout << endl;
}
void testLinkQueue() {
CircleIntQueuePtr tempPtr = initQueue();
for (int i = 10; i < 16; i++) {
EnterQueue(tempPtr, i);
}
outputLinkQueue(tempPtr);
for (int i = 0; i < 6; i++) {
printf("dequeue gets %d\r\n", DeleteQueue(tempPtr));
}
EnterQueue(tempPtr, 8);
outputLinkQueue(tempPtr);
}
int main() {
testLinkQueue();
system("pause");
return 0;
}
9.运行结果展示
三、总结
1.循环队列相比于普通的顺序存储队列来说,对空间的应用可以说是能达到非常充分的地步。
2.为了区分空队列与满队列, 需要留一个空间.
3.注意出队和入队时,对指针的处理方式。
4.循环队列依然遵循队列的特性:先进先出