提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!
提示:以下是本篇文章正文内容,下面案例可供参考
一、队列
1.1队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
**入队列:**进行插入操作的一端称为队尾
**出队列:**进行删除操作的一端称为队头
二、队列的实现
队列(先进先出)有三种实现方案: 数组、单向链表、双向链表
数组: 队列是对尾入,对头出,但是数组尾插还可以,但是头删还得挪动数据,所以非常不方便的
**单链表:**单链表尾插入队列方便,头删也方便
2.1头文件的实现---Queue.h
cpp
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
QDataType val;
struct QueueNode* next;
}QNode;
//尾入(*单向链表,我们要找尾,进行尾插,所以我们需要把头节点和尾节点的指针传进来,
//但是要进行头删,得频繁改变第一个节点得地址,所以我们得用二级指针,这样就更麻烦了)
//void QueuePush(QNode* phead,QNode* ptail, QDataType x);
头出
//void QueuePop(QNode* phead);
typedef struct Queue
{
QNode* phead;
QNode* ptail;
int size;
}Queue;
//尾入(我们把第一个节点和尾节点放入一个结构体中,
//然后可以改变结构体成员,就可以实现第一个节点地址的频繁的更换)
void QueuePush(Queue* pq, QDataType x);
//头出
void QueuePop(Queue* pq);
//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//取队头的数据
QDataType QueueFront(Queue* pq);
//取队尾的数据
QDataType QueueBack(Queue* pq);
//获取队列中有效元素个数
int QueueSize(Queue* pq);
//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);
2.2源文件的实现---Queue.c
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"
//尾入(我们把第一个节点和尾节点放入一个结构体中,
//然后可以改变结构体成员,就可以实现第一个节点地址的频繁的更换)
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->val = x;
newnode->next = NULL;
if (pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
//头出
void QueuePop(Queue* pq)
{
assert(pq);
//如果只剩一个节点的时候,phead往后走,此时ptail就是野指针
assert(pq->phead);
QNode* del = pq->phead;
pq->phead = pq->phead->next;
free(del);
del = NULL;
if (pq->phead == NULL)
{
pq->ptail = NULL;
}
pq->size--;
}
//初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
//销毁
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
}
//取队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
//取队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->val;
}
//获取队列中有效元素个数
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
2.3源文件的测试---test.c
cpp
#include "queue.h"
int main()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
while (!QueueEmpty(&q))
{
printf("%d ", QueueFront(&q));
QueuePop(&q);
}
QueueDestroy(&q);
return 0;
}
三、测试队列实际数据的展示
1、出入队列的方式:队尾插入数据,对头删除数据
2、出队列和入队列的关系:一对一的
3.1正常队列的出入
3.2入队列的同时存在出队列
总结
好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。