【数据结构】——5.1 链队列
目录
一、队列的概念及结构
1. 队列的概念
队列:只允许在一端进行插入,另一端进行删除的数据操作的特殊线性表,插入的一端叫做队头,删除的一端叫队尾
队列具有先进先出FIFO(First In First Out)的特点
队列的插入叫做入队,删除叫出队列
队列可以分为顺序队列和链队列,由于顺序队列头插需要移动大量元素,时间复杂度高,所以链队列是一个很好的选择,这里我们实现链队列和循环队列
- 顺序队列
- 链队列
2. 链队列结构声明
typedef int QDataType;
typedef struct QueueNode //队列数据节点
{
QDataType data; //数据
struct QueueNode* next; //指向下一个结点的指针
} QueueNode;
typedef struct Queue //队列
{
QueueNode* head; //头指针
QueueNode* tail; //尾指针
} Queue;
二、链队列实现
1. 初始化
- 为队列申请空间
- 初始化头尾指针,都赋值为NULL
void QueueInit(Queue** ppq)
{
assert(ppq != NULL);
*ppq = (Queue*)malloc(sizeof(Queue));
if (*ppq == NULL)
{
perror("malloc fail\n");
exit(-1);
}
(*ppq)->head = NULL;
(*ppq)->tail = NULL;
}
2. 入队列
- 先为节点申请空间,并赋值
- 入队列前先判断队列是否为空,空队列插入数据时头尾指针都要修改
void QueuePush(Queue** ppq, QDataType x)
{
assert(ppq != NULL);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
perror("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if ((*ppq)->head == NULL)
{
(*ppq)->head = newnode;
(*ppq)->tail = newnode;
}
else
{
(*ppq)->tail->next = newnode;
(*ppq)->tail = (*ppq)->tail->next;
}
}
3. 出队列
- 先判读队列是否为空(这里对空队列不做处理)
- 若是队列只剩一个节点,则出队列后头尾指针都要修改为NULL
void QueuePop(Queue** ppq)
{
assert(ppq != NULL);
if (QueueEmpty(*ppq))
{
return;
}
if ((*ppq)->head == (*ppq)->tail)
{
free((*ppq)->head);
(*ppq)->head = NULL;
(*ppq)->tail = NULL;
}
else
{
QueueNode* next = (*ppq)->head->next;
free((*ppq)->head);
(*ppq)->head = next;
}
}
4. 获取队头元素
- 队列为空断言处理
- 直接返回头指针指向的数据
QDataType QueueFront(Queue* pq)
{
assert(pq != NULL);
assert(!QueueEmpty(pq));
return pq->head->data;
}
5. 获取队尾元素
- 队列为空断言处理
- 直接返回尾指针指向的数据
QDataType QueueBack(Queue* pq)
{
assert(pq != NULL);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
6. 获取元素个数
遍历队列,使用计数器记录元素个数
size_t QueueSize(Queue* pq)
{
size_t count = 0;
QueueNode* cur = pq->head;
while (cur != NULL)
{
count++;
cur = cur->next;
}
return count;
}
7. 判断队列是否为空
若是头指针为NULL,则队列为空
_Bool QueueEmpty(Queue* pq)
{
return pq->head == NULL;
}
8. 销毁
- 遍历队列,依次释放节点
- 最后释放队列,并将队列指针置为NULL
void QueueDestroy(Queue** ppq)
{
assert(ppq != NULL);
QueueNode* cur = (*ppq)->head;
while (cur != NULL)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
free(*ppq);
*ppq = NULL;
}
三、完整代码
代码保存在gitee中:点击完整代码参考