循环队列是一个大小确定的特殊队列,它的特殊体现在循环,之前提到的普通队列,我们是用链表来实现的,在这里,由于循环队列是一个长度确定的队列,所以我们可以拿顺序表来实现。循环队列的操作与普通队列类似,不过不同的地方在于当rear走到capacity-1并且front在0号元素位置的时候,当此时再有元素入队,则不能入队,如果此时有元素出队,则可以继续入队。
代码实现
1.定义链表
typedef struct CircleQueue
{
int data[TOTAL_SPACE];
int head;
int tail;
} *CircleQueuePtr;
2.初始化
CircleQueuePtr initCircleQueue()
{
CircleQueuePtr resultPtr = (CircleQueuePtr)malloc(sizeof(struct CircleQueue));
resultPtr->head = 0;
resultPtr->tail = 0;
return resultPtr;
}
3.打印
void outputQueue(CircleQueuePtr paraPtr)
{
int i;
if(paraPtr->head == paraPtr->tail)
{
printf("队列为空.\n");
return;
}
printf("队列:");
for(i = paraPtr->head;i < paraPtr->tail;i++)
{
printf("%d ",paraPtr->data[i % TOTAL_SPACE]);
}
printf("\n");
}
4.入队
void enterQueue(CircleQueuePtr paraPtr,int paraData)
{
if((paraPtr->tail+1) % TOTAL_SPACE == paraPtr->head)
{
printf("队列已满.\n");
return;
}
paraPtr->data[paraPtr->tail%TOTAL_SPACE] = paraData;
paraPtr->tail++;
}
5.出队
int deleteQueue(CircleQueuePtr paraPtr)
{
int result;
if(paraPtr->head == paraPtr->tail)
{
printf("队列为空,不能删除.\n");
return -1;
}
result = paraPtr->data[paraPtr->head % TOTAL_SPACE];
paraPtr->head++;
return result;
}
6.测试代码
void queueText()
{
CircleQueuePtr tempPtr = initCircleQueue();
int i;
for(i = 9;i < 15;i++)
{
enterQueue(tempPtr,i);
}
outputQueue(tempPtr);
for(i = 0;i < 4;i++)
{
printf("删除%d\n",deleteQueue(tempPtr));
}
outputQueue(tempPtr);
for(i = 0;i<3;i++)
{
printf("删除%d\n",deleteQueue(tempPtr));
}
}
7.输出结果
队列已满.
队列:9 10 11 12 13
删除9
删除10
删除11
删除12
队列:13
删除13
队列为空,不能删除.
删除-1
队列为空,不能删除.
删除-1
总结
为了解决顺序存储结构中队列实现时时间复杂度的问题,我们采用了循环队列并实现了其基本的入队、出队等操作。那么和栈一样,队列作为一个逻辑为线性结构的数据结构,除了使用顺序存储实现,还可以使用链式存储实现