1.什么是队列?
队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out) ;
入队列:进行插入操作的一端称为队尾;
出队列:进行删除操作的一 端称为队头;
2.队列的实现
队列可以用数组(静态或者动态)和链表的结构来实现,使用链表会更优一点,因为使用数组的话出队列需要数据的移动,时间复杂度为o(n),效率会低一点。
使用单链表实现的队列:
3.队列具体实现
3.1队列节点和队列
3.2队列初始化
3.3入队/尾插
3.4出队/头删
注意这里节点情况要分类讨论,防止q->tail变为野指针。
3.5获取队头数据
3.6获取队尾数据
3.7检测队列是否为空
3.8销毁队列
4.代码
//Queue.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
// 链式结构表示队列
typedef struct QListNode
{
//next指针
struct QListNode* next;
//数据
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
//记录队列头节点
QNode* head;
//记录队列尾节点
QNode* tail;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
//Queue.c
#include"Queue.h"
// 初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->head = q->tail = NULL;
}
// 队尾入队列//尾插
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("Malloc Fail");
exit(1);
}
if (q->head == NULL)
{
q->head = q->tail = newnode;
newnode->data = data;
newnode->next = NULL;
}
else
{
q->tail->next = newnode;
newnode->data = data;
newnode->next = NULL;
q->tail = newnode;
}
}
// 队头出队列//头删
void QueuePop(Queue* q)
{
assert(q);
//队列为空不能删
assert(q->head);
//只有一个节点的情况
if (q->head == NULL)
{
free(q->head);
q->head = q->tail = NULL;
return;
}
//队列多个节点
QNode* temp = q->head->next;
free(q->head);
q->head = temp;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
//空队列调用
assert(q->head);
//队列不为空
return q->head->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
//空队列调用
assert(q->head);
//队列不为空
return q->tail->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
QNode* pcur = q->head;
while (pcur)
{
count++;
pcur = pcur->next;
}
return count;
}
// 检测队列是否为空
bool QueueEmpty(Queue* q)
{
assert(q);
return q->head == NULL;
}
// 销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* pcur = q->head;
//循环遍历
while (pcur)
{
QNode* temp = pcur->next;
free(pcur);
pcur = temp;
}
//置空
q->head = q->tail = NULL;
}
//Test.c
#include"Queue.h"
void test1()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
printf("%d\n", QueueFront(&q));
printf("%d\n", QueueBack(&q));
printf("%d\n", QueueSize(&q));
while (!QueueEmpty(&q))
{
printf("%d ", QueueFront(&q));
QueuePop(&q);
}
printf("\n%d\n", QueueSize(&q));
QueueDestroy(&q);
}
int main()
{
test1();
return 0;
}