队列
1.队列基本概念
队列和栈一样,是对于数据的存和取有严格要求的线性存储结构。
队列与栈的区别在于,队列的两端都是开口,要求数据只能从一段进,从另一端出。
队头
——出数据的一端
队尾
——进数据的一端
队列中的数据遵循先进先出(FIFO,First In First Out)的原则,如图,元素1首先进队,那1也将率先出队,元素3最后进队,也将最后出队。
2.队列的实现
由于线性表即可实现队的结构,故单链表和顺序表皆可。但是顺序表在实现队列出队后,将剩余元素前移效率很低
(除非使用循环队列,但存在上限)。本文将实现链表结构的队列。
队列的基本操作有
- 初始化队列
void QueueInit(Queue* pq);
- 检测队列是否为空
bool QueueEmpty(Queue* pq);
- 队尾处入队
void QueuePush(Queue* pq, QDataType x);
- 队头处出队
QDataType QueuePop(Queue* pq);
- 获取队头处元素
QDataType QueueFront(Queue* pq);
- 获取队尾元素
QDataType QueueBack(Queue* pq);
- 获取队列中有效元素的个数
int QueueSize(Queue* pq);
- 销毁队列
void QueueDestroy(Queue* pq);
2.1 基本数据类型
typedef int QDataType;
//结点链式结构
typedef struct QNode
{
QDataType data;
struct QNode* next;
}QNode;
//队列结构
typedef struct Queue
{
QNode* head;//队头:出队
QNode* tail;//队尾:入队
}Queue;
2.1 初始化队列
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
2.2 检测队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
2.3 队尾处入队
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
//创建结点
QNode* newnode = (QNode*)malloc(sizeof(QNode));
assert(newnode);
newnode->data = x;
newnode->next = NULL;
//接入到队尾
//如果head为NULL
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
2.4 队头处出队
QDataType QueuePop(Queue* pq)
{
assert(pq);
//队列不为空
assert(!QueueEmpty(pq));
//记录队列第二个元素的位置
QNode* second_place=pq->head->next;
free(pq->head);
pq->head = second_place;
//如果删除的是最后一个元素,记得把tail置为NULL,否则tail将会成为野指针,指向已被free的空间
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
2.5 获取队头处元素
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
2.6 获取队尾元素
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
2.7 获取队列中有效元素的个数
int QueueSize(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
int count = 0;
while (cur)
{
QNode* post = cur->next;
count++;
cur = post;
}
return count;
}
2.8 销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* post = cur->next;
free(cur);
cur = post;
}
pq->head = pq->tail = NULL;
}
3.功能展示
#include "Queue.h"
void TestQueue1()
{
Queue q;
QueueInit(&q);
//入队
printf("入队1 2 3 4\n");
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
//获取队列个数
printf("元素个数:%d\n", QueueSize(&q));
//QueueDestroy(&q);
//获取队头元素
printf("队头元素=%d\n", QueueFront(&q));
//出队
printf("出队\n");
QueuePop(&q);
printf("队头元素=%d\n", QueueFront(&q));
//获取队尾元素
printf("队尾元素=%d\n", QueueBack(&q));
}
int main()
{
TestQueue1();
return 0;
}
青山不改 绿水长流