目录
队列_Queue
【1】队列的概念及结构
【2】节点队列的实现
【2.1】队列的各个接口
【2.2】队列的初始化
【2.3】队列栈的释放
【2.4】队尾入队列
【2.5】队头出队列
【2.6】获取队列头部元素
【2.7】获取队列尾部元素
【2.8】获取队列中有效元素个数
【2.9】检测队列是否为空
队列_Queue
【1】队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 。
栈符合后进先出(First In First Out )
【2】节点队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
【2.1】队列的各个接口
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
// 栈数据结构定义 ///
/* 栈数据结构 */
typedef int QDataType;
typedef struct QListNode {
QDataType _data;
struct QListNode *_nextNode;
}QNode;
typedef struct Queue {
QNode* _head;
QNode* _tail;
size_t _size;
}Q;
// 栈常用接口定义 ///
/* 队列:初始化 */
void QueueInit(Q* q);
/* 队列:销毁 */
void QueueDestroy(Q* q);
/* 队列:尾插 */
void QueuePush(Q* q, QDataType val);
/* 队列:头出 */
void QueuePop(Q* q);
/* 队列:获取头部数据 */
QDataType QueueFront(Q* q);
/* 队列:获取尾部数据 */
QDataType QueueBack(Q* q);
/* 队列:获取队列有效元素个数 */
size_t QueueSize(Q* q);
/* 队列:检查是否为空栈 */
bool QueueEmpty(Q* q);
【2.2】队列的初始化
/* 队列:初始化 */
void QueueInit(Q* q) {
// 断言
assert(q);
// 初始化
q->_head = q->_tail = NULL;
q->_size = 0;
}
【2.3】队列栈的释放
/* 队列:销毁 */
void QueueDestroy(Q* q) {
// 断言
assert(q);
// 遍历释放
QNode* pCur = q->_head;
while (pCur != NULL) {
QNode* pDel = pCur;
pCur = pCur->_nextNode;
free(pDel); pDel = NULL;
}
// 初始化
q->_head = q->_tail = NULL;
q->_size = 0;
}
【2.4】队尾入队列
- 入队列动画演示
- 入队会出现两种情况
/* 队列:尾插 */
void QueuePush(Q* q, QDataType val) {
// 断言
assert(q);
// 开辟节点
QNode* newNode = (QNode*)malloc(sizeof(QNode));
// 开辟失败
if (newNode == NULL) {
perror("malloc fail!");
exit(-1);
}
// 开辟成功
else
{
newNode->_data = val;
newNode->_nextNode = NULL;
}
// 插入数据
// 链表为空
if (q->_tail == NULL) {
q->_head = q->_tail = newNode;
}
// 链表不为空
else
{
q->_tail->_nextNode = newNode;
q->_tail = q->_tail->_nextNode;
}
// 记录数据个数
q->_size++;
}
【2.5】队头出队列
/* 队列:头出 */
void QueuePop(Q* q) {
// 断言
assert(q);
// 链表剩余最后一个节点数据
if (q->_head->_nextNode == NULL) {
free(q->_head);
q->_head = q->_tail = NULL;
}
// 链表有很多数据
else
{
QNode* pDel = q->_head;
q->_head = q->_head->_nextNode;
free(pDel); pDel = NULL;
}
}
【2.6】获取队列头部元素
/* 队列:获取头部数据 */
QDataType QueueFront(Q* q) {
// 断言
assert(q);
// 检测是否是空
assert(!QueueEmpty(q));
return q->_head->_data;
}
【2.7】获取队列尾部元素
/* 队列:获取尾部数据 */
QDataType QueueBack(Q* q) {
// 断言
assert(q);
// 检测是否是空
assert(!QueueEmpty(q));
return q->_tail->_data;
}
【2.8】获取队列中有效元素个数
/* 队列:获取队列有效元素个数 */
size_t QueueSize(Q* q) {
// 断言
assert(q);
return q->_size;
}
【2.9】检测队列是否为空
/* 队列:检查是否为空栈 */
bool QueueEmpty(Q* q) {
// 断言
assert(q);
return q->_head == NULL && q->_tail == NULL;
}