携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
什么是队列
队列也是一种特殊的线性结构。它只允许在一端进行插入数据,在另一端删除数据。插入数据叫做入队列,删除数据叫做出队列。在队尾插数据,在队头删数据。
实现队列
我们可以用类似链表的结构实现它。每个节点都包括一个数据,以及下一个节点的地址。由于队列的特殊性质(头删,尾插),所以我们包装两个指针,一个指针指向队头,一个指针指向队尾。
创建类型
节点类型
typedef int QueueTypeDate;
typedef struct QListNode
{
struct QListNode* next;
QueueTypeDate val;
}QNode;
由两个指针维护的队列
因为指针指向的是队列的节点,所以它的类型为节点指针的类型
即QNode*
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
初始化队列
置为空即可
void QueueInit(Queue* q)
{
assert(q);
q->head = q->tail = NULL;
}
队列是否为空
bool QueueEmpty(Queue* q)
{
assert(q);
return q->head == NULL;
}
入队列
入队列是从队列的尾进行插入的。 入队列的时候要判断队列是否为空,当为空的时候,头就要变。
void QueuePush(Queue* q, QueueTypeDate x)
{
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
newnode->next = NULL;
newnode->val = x;
if (QueueEmpty(q))
q->head = q->tail = newnode;
else
{
q->tail->next = newnode;
q->tail = newnode;
}
}
出队列
出队列是从队头进行出数据的。 要注意两点 1.队列为空的时候不能进行出队操作 2.当队列中只有一个数据的时候,不能只改变队列的头,其队列的尾也要同时改变。
void QueuePop(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
if (q->head == q->tail)
{
free(q->head);
q->head = q->tail = NULL;
}
else
{
QNode* next = q->head->next;
free(q->head);
q->head = next;
}
}
队列的销毁
销毁的过程就是不断出队列的过程
void QueueDestroy(Queue* q)
{
assert(q);
while (q->head)
{
QueuePop(q);
}
}
获得队头的数据
首先保证队列不能为空
QueueTypeDate QueueFront(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->head->val;
}
获得队尾的数据
首先保证队列不能为空
QueueTypeDate QueueBack(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->tail->val;
}
队列中的数据的个数
int QueueSize(Queue* q)
{
assert(q);
QNode* cur = q->head;
int size = 0;
while (cur)
{
size++;
cur = cur->next;
}
return size;
}