队列时一种抽象数据类型,其主要特点就是有一个队首和队尾,队首出元素,队尾进元素。队列的实现用链表是十分简单的,只需要用到头删和尾增两个功能函数。而使用数组实现队列会有一定程度上的问题出现,如下图
这种情况就是由一开始队尾进来十二个元素,后来队首走掉三个元素造成的情况(也可以是其它情况,只需要能造成这样的结果即可)
这样一来,明明队中还有位置,但无法使用,这时候可以采取循环队列的方式来进行解决,也就是当再进来一个人的时候,队尾移到前面(注意:队列增加元素只能从队尾增加),如下图:
这样一来,队列的声明貌似就显得十分简单了。构思一下:我们首先需要两个能够记录数字的内存来记录队首和队尾相对于第一个空格的位置(第一个空格即为0,就是按照数组的表示方法),然后我们还需要一个能够记录队列中元素的个数的变量(这样就可以从队首到队尾按元素个数进行遍历了),最后还需要一个指针和一个容量来记录这个队列最大的大小以及这个队列在内存中的位置,所以,接下来是队列抽象数据类型的声明
typedef int EleType_queue;
typedef struct queue
{
int front;
int rear;
int capacity;//record the maxnum of the queue
int size;//record the existing member in the queue
EleType_queue* arr;
}queue;
1.创建队列
该功能实现队列的创建,对主调函数给的值来创建队列的大小。
queue* CreatQueue(int maxnum)
{
queue* Q = (queue*)malloc(sizeof(queue));
Q->capacity = maxnum;
Q->arr = (EleType_queue*)malloc(sizeof(EleType_queue) * maxnum);
Q->front = 0;
Q->rear = -1;
Q->size = 0;
return Q;
}
2.队尾进入元素
该功能实现队尾进入元素,并且注意队尾指向最后一个空格的情况及队列已满的情况
void Enqueue(queue* Q, EleType_queue value)
{
if (Q->size >= Q->capacity)
{
printf("队列已满");
return;
}
if(Q->rear + 1 <= Q->capacity-1)
Q->arr[++(Q->rear)] = value;
else
{
Q->rear = 0;
Q->arr[Q->rear] = value;
}
Q->size++;
}
3.队首删除元素
该功能实现队首删除元素,并且注意队中存在元素为零的情况,以及队首位于最后一个空格的情况
void Dequeue(queue* Q)
{
if (Q->front + 1 <= Q->capacity - 1)
Q->front++;
else
{
Q->front = 0;
}
Q->size--;
}
4.打印队列
代码如下
void PrintQueue(queue* Q)
{
int i = 0;
for (i = 0; i < Q->size; i++)
{
if(Q->front + i <= Q->capacity - 1 )
printf("%d ", Q->arr[Q->front + i]);
else
{
printf("%d ", Q->arr[Q->front + i - (Q->capacity)]);
}
}
}