1.队列
队列是一种数据结构,这种结构的特点是先进先出,后进后出。有点类似于数组只能尾插和头删。不过我们不用数组实现队列,因为数组的头删需要挪动后面所有的数据,成本过高。我们采用单链表来实现队列.
2.代码实现
Queue.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//我们使用链表的结构实现队列,因为如果使用数组出队列就要挪动后面所有元素成本太高
typedef int QueueDataType;
typedef struct QueueNode
{
QueueDataType val;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
//为了便于头部删除和尾部插入
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueInsert(QNode* pq, QueueDataType data);
void QueuePop(Queue* pq);
QueueDataType QueueFront(Queue* pq);//获取队列首元素
QueueDataType QueueBack(Queue* pq);//获取队列尾部元素
bool QueueEmpty(Queue* pq);//判断队列是否为空
int QueueSize(Queue* pq);//队列中有效元素的个数
void QueueDestroy(Queue* pq);//销毁队列
Queue.c
#include "Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
QNode* BuyQNode(QueueDataType data)
{
QNode* newNode = malloc(sizeof(QNode));
if (newNode == NULL)
{
printf("malloc fail\n");
exit(1);
}
newNode->next = NULL;
newNode->val = data;
return newNode;
}
void QueueInsert(Queue* pq, QueueDataType data)
{
assert(pq);
QNode* newNode = BuyQNode(data);
if (pq->head == NULL)
{
//说明是插入第一个节点
pq->head = pq->tail = newNode;
return;
}
//不是插入第一个节点
pq->tail->next = newNode;
pq->tail = newNode;
}
void QueuePop(Queue* pq)
{
assert(pq);
if (!QueueEmpty(pq))
{
if (pq->head == pq->tail)
{
//只有一个 元素
free(pq->head);
pq->head = pq->tail = NULL;
return;
}
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
return;
}
printf("队列中无元素\n");
}
bool QueueEmpty(Queue* pq)
{
if (pq->head == NULL)
{
return true;
}
return false;
}
QueueDataType QueueFront(Queue* pq)
{
assert(pq);
if (QueueEmpty(pq))
{
printf("队列中无元素\n");
return;
}
return pq->head->val;
}
QueueDataType QueueBack(Queue* pq)
{
assert(pq);
if (QueueEmpty(pq))
{
printf("队列中无元素\n");
return;
}
return pq->tail->val;
}
int QueueSize(Queue* pq)
{
assert(pq);
int ret = 0;
if (!QueueEmpty(pq))
{
ret = 1;
while (pq->head != pq->tail)
{
pq->head = pq->head->next;
ret++;
}
}
return ret;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
while (!QueueEmpty(pq))
{
QueuePop(pq);//这里直接掉pop就行,在pop的时候,已经帮我们释放了资源,并且在最后一个节点释放之后,head和tail都被置为NULL
}
}