队列的定义和使用场景
队列是一种先进先出(FIFO)的数据结构,在现实的生活中我们常常使用到队列这一结构,比如需要按照先后顺序处理数据的场景,比如任务调度、消息传递等。
队列代码需要的自取:
void QueueInit(Queue* pq)
{
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDatatype x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return -1;
}
newnode->val = x;
newnode->next = NULL;
if (pq->phead == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->phead);
QNode* tmp = pq->phead;
pq->phead = pq->phead->next;
free(tmp);
tmp = NULL;
if (pq->phead == NULL)
pq->ptail = NULL;
pq->size--;
}
QDatatype QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
QDatatype QueueBack(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->ptail->val;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
int QueueSize(Queue* pq)
{
return pq->size;
}
对列的特点:
队列具有以下5种特点:
1. 元素按照添加的顺序排列,先添加的元素在队列的前面,后添加的元素在队列的后面。
2. 只能在队列的一端(称为队尾)添加元素,而在另一端(称为队头)删除元素。
3. 只能访问队头的元素,不能访问队尾的元素。
4. 队列的长度可以动态增长,没有固定的容量限制。
5. 队列可以用数组或链表来实现。
用链表来实现队列
1、 初始化队列
思路解析:
直接把指针都置为空,size置为0即可。
代码实现:
void QueueInit(Queue* pq)
{
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
2、 队尾入队列
思路解析:
1、当第一次进入时要把指针都指向第一个节点。
2、当除第一次进入时就当做是尾插在最后面即可。
3、注意size要根据数据的变动而变动。
代码实现:
void QueuePush(Queue* pq, QDatatype x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return -1;
}
newnode->val = x;
newnode->next = NULL;
if (pq->phead == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
3、队头出队列(本函数需要的是弹出数据)
思路解析:
即要改变链表的第一个指针的指向,让指向头节点的指针指向第二个节点,free第一个节点然后把free的指针置为空,然后size--即可。
代码实现:
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->phead);
QNode* tmp = pq->phead;
pq->phead = pq->phead->next;
free(tmp);
tmp = NULL;
if (pq->phead == NULL)
pq->ptail = NULL;
pq->size--;
}
4 获取队列头部元素
思路解析:
利用头指针指向第一个节点然后返回第一个节点的val即可。
代码展示:
QDatatype QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
5 获取队列队尾元素
思路解析:
利用尾指针指向的最后一个节点访问其中的val值即可。
代码实现:
QDatatype QueueBack(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->ptail->val;
}
6 获取队列中有效元素个数
思路解析:
直接返回结构体中的size值即可。
代码展示:
void QueueSize(Queue* pq)
{
return pq->size;
}
7 检测队列是否为空,如果为空返回非零结果,如果非空返回0
思路解析:
1、利用if else来判断队列是否为空根据判断来返回0或非0。
2、在C99之后引入的一个新变量bool,bool会根据需要判断的内容返回0或非0值。
代码展示:
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
8 销毁队列
思路解析:
回收结构体把指针都置为空size也置为空即可。
代码展示:
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
今天给大家介绍了队列的实现,还请大家多多关注,如果有什么错误还请大佬指出。