基于数组的循环队列
如下图所示,基于数组的循环队列,有3种形态:
1,队列为空,这个时候front等于rear,如下图左边部分所示。
2,正常形态,这个时候,front指向队首元素,rear指向队尾元素的下一个位置,如下图中间部分所示。
3,队列满,这个时候,队尾指针指向队首指针的前一个位置(空位)。如下图右边部分所示。
因此,循环队列在队列满的时候,会浪费一个空间,这主要是为了区分队列空和队列满的2个状态的。否则,如果最后一个空间也存放元素,那么rear在加1后,就和front相等了,这和队列为空的判断条件是冲突的。
在实现基于数组的队列的基本操作的时候,结合上面3个队列的基本形态来写代码,会显得思路清晰。下面是具体的代码与数据结构(注意,在多线程环境下,下面的代码没有提供加锁机制,需要另外处理):
#define MAXSIZE 100//数组的元素个数
int Queue[MAXSIZE]={0};//队列的底层数据结构,数组,支持100个元素
int rear = 0;//队列后端,插入的位置
int front = 0;//队列前端,删除的位置
创建队列,将前端和后端置0
int CreateQueue()
{
rear = front = 0;
return 1;
}
判断队列是否为空
int IsQueueEmpty()
{
return rear==front?1:0;//front等于rear,队列即为空
}
判断队列是否满
int IsQueueFull()
{
return (rear+1)%MAXSIZE == front?1:0;//注意判断标准
}
入队:
int EnQueue(int e)
{
if(IsQueueFull())
{
return -1;
}
Queue[rear]=e;
rear = (rear+1)%MAXSIZE;
return 1;
}
出队
int DeQueue(int *e)
{
if(IsQueueEmpty())
{
return -1;
}
if (e==NULL)
{
return -1;
}
*e = Queue[front];
front = (front + 1)%MAXSIZE;
return 1;
}
队列遍历:
void TraverseQue()
{
while(!IsQueueEmpty())
{
int val;
DeQueue(&val);
printf("%d ",val);
}
printf("\n");
}
接口测试:
int _tmain(int argc, _TCHAR* argv[])
{
for(int i=0;i<200;i++)
{
EnQueue(i);
}
int val = 0;
DeQueue(&val);
printf("val:%d\n",val);
DeQueue(&val);
printf("val:%d\n",val);
TraverseQue();
return 0;
}