队列,是一种先进先出的数据结构,其表现如下图所示:
有别于栈,在C语言中,我们使用链表来构建队列,插入数据时,使用尾插法,弹出元素时,使用头删法,其具体实现如下:
typedef int QDataType;
typedef struct QuequeNode
{
QDataType value;
struct QuequeNode* next;
} QuequeNode;
typedef struct Queque
{
QuequeNode* head;
QuequeNode* end;
int size;
} Queque;
void InitQue(Queque*que)
{
assert(que);
que->head = NULL;
que->end = NULL;
que->size = 0;
}
void PushQue(Queque* que,QDataType v)
{
assert(que);
if (que->size == 0)
{
que->head = (QuequeNode*)malloc(sizeof(QuequeNode));
que->end = que->head;
que->head->value = v;
que->head->next = NULL;
que->size ++;
}
else
{
que->end->next = (QuequeNode*)malloc(sizeof(QuequeNode));
que->end = que->end->next;
que->end->value = v;
que->end->next = NULL;
que->size++;
}
}
void PopQue(Queque* que)
{
assert(que);
QuequeNode* temp = que->head;
que->head = que->head->next;
free(temp);
que->size--;
}
QDataType QueTop(Queque* que)
{
assert(que);
return que->head->value;
}
void DestoryQue(Queque* que)
{
assert(que);
if (que->size == 0)
{
return;
}
que->size = 0;
QuequeNode* temp1 = que->head;
QuequeNode* temp2 = NULL;
while (temp1)
{
temp2 = temp1;
temp1 = temp1->next;
free(temp2);
}
que->head = NULL;
que->end = NULL;
}
在了解了队列的结构后,我们来解决循环列表问题。
循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
力扣连接:. - 力扣(LeetCode)
循环队列要求队列空间大小一定,因此我们可以使用数组来实现
如图,队尾索引为end,队头索引为head,队内元素个数为size,队的容量为capacity,其基本代码结构如下:
typedef struct
{
int*a;
int end;
int head;
int capacity;
int size;
} MyCircularQueue;
开始时end=-1,head=0,size=0,当有数据插入时,end前移加1,size+1,当有数据弹出时,head前移加1,size-1,同时如果size等于capacity时,不可再加元素,size等于0时,不可再弹出元素,在满足size条件的情况下,如果head或end将要加一时若加一后等于capacity,为防止越界,将其设为0。其具体代码如下:
typedef struct
{
int*a;
int end;
int head;
int capacity;
int size;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k)
{
MyCircularQueue* queque = (MyCircularQueue*)malloc(sizeof (MyCircularQueue));
queque->a = (int*)malloc(k*sizeof(int));
queque->end = -1;
queque->head = 0;
queque->size = 0;
queque->capacity = k;
return queque;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
if(obj->size==obj->capacity)
{
return false;
}
else
{
obj->end++;
if(obj->end+1>obj->capacity)
{
obj->end = 0;
}
obj->a[obj->end] = value;
obj->size++;
return true;
}
}
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
if(obj->size == 0)
{
return false;
}
obj->head++;
if(obj->head+1 > obj->capacity)
{
obj -> head = 0;
}
obj->size--;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj)
{
if(obj->size==0)
{
return -1;
}
return obj->a[obj-> head];
}
int myCircularQueueRear(MyCircularQueue* obj)
{
if(obj->size==0)
{
return -1;
}
else
{
return obj->a[obj->end];
}
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
return obj->size==0;
}
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
return obj->size==obj->capacity;
}
void myCircularQueueFree(MyCircularQueue* obj)
{
free(obj->a);
free(obj);
}