数据学习之队列

栈和队列是两个相似又相反的数据结构类型,但是受限于写栈的时候作者的时间和精力紧张就没有将两者放到一起,所以本篇我们将接着栈的内容继续深入学习与栈相对的另一种数据结构:队列

作者的个人gitee:楼田莉子 (riko-lou-tian) - Gitee.com

目录

概念

队列结构的实现

初始化队列

入队

判断队列是否为空

出队

取数据

取队头数据

取队尾数据

size()

源代码:


概念

只允许一端插入数据操作,另一端进行删除操作的特殊线性表。

栈遵循**"后进先出"** ,而队列遵循**"先进先出"**的原则

入队列:进行插入操作的一端是队尾

出队列:进行删除操作的一端是队头

底层结构是这样的

我们要用一个单链表实现队列。先确认一个单链表

队列结构的实现

因为队列是通过类似链表的结构模拟的,所以我们需要先定义一个"结点"的结构

cpp 复制代码
typedef int QTypeData;
//队列结点结构
typedef struct queuenode
{
	QTypeData data;
	struct queuenode* next;
}QN;

接下来我们根据结点定义队列的结构

cpp 复制代码
//队列结构
typedef struct queue
{
	QN* phead;//队头指针
	QN* ptail;//队尾指针
	//频繁调用的时候需要用到size
	//int size;//队列长度
}queue;

这样就完成了。

初始化队列

接下来我们要初始化队列

cpp 复制代码
//初始化队列
void initqueue(queue* pq)
{
	assert(pq!= NULL);
	pq->phead = pq->ptail = 0;
}

入队

cpp 复制代码
//入队-队尾入队
void enqueue(queue* pq, QTypeData data)
{
	assert(pq!= NULL);
	QN*new_node=(QN*)malloc(sizeof(QN));
	//队列空间申请失败
	if (new_node == NULL)
	{
		perror("malloc 失败");
		exit(1);
	}
	new_node->data = data;
	new_node->next = NULL;
	//判断队列是否为空
	if (pq->phead==NULL)
	{
		//队列为空,则new_node既是头结点也是尾结点
		pq->phead = pq->ptail = new_node;
	}
	else
	{
		//队列不为空,则new_node是尾结点
		pq->ptail->next = new_node;
		pq->ptail = pq->ptail->next;
	}
	//方式二:
	//++pq->size;
}

判断队列是否为空

出队的时候需要判断链表是否为空否则就会导致野指针的问题,因此在写出队列之前我们要先写一个判断队列是否为空的函数。

C语言中bool类型的函数必须包含头文件<stdbool.h>

cpp 复制代码
//判断队列是否为空
bool isempty(queue* pq)
{
	assert(pq!= NULL);
	return pq->phead == NULL;
}

出队

cpp 复制代码
//出队---队头出队
void dequeue(queue* pq)
{
	assert(!isempty(pq));
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QN*next=pq->phead->next;
		free(pq->phead);
		pq->phead=next;
	}
	//方式二:
	//--pq->size;
}

取数据

取队头数据

cpp 复制代码
//取队头数据
QTypeData gethead(queue* pq)
{
	assert(!isempty(pq));
	return pq->phead->data;
}

取队尾数据

cpp 复制代码
//取队尾数据
QTypeData gettail(queue* pq)
{
	assert(!isempty(pq));
	return pq->ptail->data;
}

size()

cpp 复制代码
//取队列长度
int size(queue* pq)
{
	QN* new_node = pq->phead;
	int count = 0;
	while (new_node != NULL)
	{
		count++;
		new_node = new_node->next;
	}
	return count;
}

测试:

cpp 复制代码
void que_test1()
{
	queue q;
	initqueue(&q);//初始化队列
	enqueue(&q, 1);//入队
	enqueue(&q, 2);
	enqueue(&q, 3);
	enqueue(&q, 4);
	dequeue(&q);//出队
	int x=gethead(&q);//获取队首元素
	printf("x=%d\n", x);
	int y=gettail(&q);//获取队尾元素
	printf("y=%d\n", y);
	//队列长度
	printf("size=%d\n",size(&q));
	destroyqueue(&q);//销毁队列
	
}
int main()
{
	que_test1();
	return 0;
}

结果为:

源代码:

queue.h

cpp 复制代码
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QTypeData;
//队列结点结构
typedef struct queuenode
{
	QTypeData data;
	struct queuenode* next;
}QN;
//队列结构
typedef struct queue
{
	QN* phead;//队头指针
	QN* ptail;//队尾指针
	//频繁调用的时候需要用到size
	//int size;//队列长度
}queue;
//初始化队列
void initqueue(queue* pq);
//入队
void enqueue(queue* pq, QTypeData data);
//出队
void dequeue(queue* pq);
//判断队列是否为空
bool isempty(queue* pq);
//取队头数据
QTypeData gethead(queue* pq);
//取队尾数据
QTypeData gettail(queue* pq);
//销毁队列
void destroyqueue(queue* pq);
//取队列长度
int size(queue* pq);

queue.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"queue.h"
//初始化队列
void initqueue(queue* pq)
{
	assert(pq!= NULL);
	pq->phead = pq->ptail = 0;

}
//入队-队尾入队
void enqueue(queue* pq, QTypeData data)
{
	assert(pq!= NULL);
	QN*new_node=(QN*)malloc(sizeof(QN));
	//队列空间申请失败
	if (new_node == NULL)
	{
		perror("malloc 失败");
		exit(1);
	}
	new_node->data = data;
	new_node->next = NULL;
	//判断队列是否为空
	if (pq->phead==NULL)
	{
		//队列为空,则new_node既是头结点也是尾结点
		pq->phead = pq->ptail = new_node;
	}
	else
	{
		//队列不为空,则new_node是尾结点
		pq->ptail->next = new_node;
		pq->ptail = pq->ptail->next;
	}
	//方式二:
	//++pq->size;
}
//判断队列是否为空
bool isempty(queue* pq)
{
	assert(pq!= NULL);
	return pq->phead == NULL;
}
//出队---队头出队
void dequeue(queue* pq)
{
	assert(!isempty(pq));
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QN*next=pq->phead->next;
		free(pq->phead);
		pq->phead=next;
	}
	//方式二:
	//--pq->size;
}
//取队头数据
QTypeData gethead(queue* pq)
{
	assert(!isempty(pq));
	return pq->phead->data;
}
//取队尾数据
QTypeData gettail(queue* pq)
{
	assert(!isempty(pq));
	return pq->ptail->data;
}
//销毁队列
void destroyqueue(queue* pq)
{
	assert(pq != NULL);
	QN* new_node = pq->phead;
	while (new_node != NULL)
	{
		QN*next=new_node->next;
		free(new_node);
		new_node=next;
	}
	pq->phead = pq->ptail = NULL;
}
//取队列长度
int size(queue* pq)
{
	assert(!isempty(pq));
	//适用于不频繁调用的情况
	 QN* new_node = pq->phead;
	int count = 0;
	while (new_node != NULL)
	{
		count++;
		new_node = new_node->next;
	}
	return count;
	//适用于频繁调用的情况
	//return pq->size;
	//但是出队列size--
}

test.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"queue.h"
void que_test1()
{
	queue q;
	initqueue(&q);//初始化队列
	enqueue(&q, 1);//入队
	enqueue(&q, 2);
	enqueue(&q, 3);
	enqueue(&q, 4);
	dequeue(&q);//出队
	int x=gethead(&q);//获取队首元素
	printf("x=%d\n", x);
	int y=gettail(&q);//获取队尾元素
	printf("y=%d\n", y);
	//队列长度
	printf("size=%d\n",size(&q));
	destroyqueue(&q);//销毁队列
	
}
int main()
{
	que_test1();
	return 0;
}

本篇内容到这里就结束了,求一个点赞,谢谢

封面图自取:

相关推荐
weixin_470740361 分钟前
某算法的python执行汇编
汇编·python·算法
是乐谷1 小时前
燧原科技招大模型训练算法工程师
科技·算法
海绵宝宝汉堡包1 小时前
c# 项目 文件夹
开发语言·c#
YuTaoShao1 小时前
【LeetCode 热题 100】139. 单词拆分——(解法一)记忆化搜索
java·算法·leetcode·职场和发展
小白要加油努力2 小时前
C++设计模式--策略模式与观察者模式
开发语言·c++·设计模式
小马学嵌入式~2 小时前
数据结构:队列 二叉树
c语言·开发语言·数据结构·算法
Slaughter信仰3 小时前
深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第二章知识点问答(21题)
java·开发语言·jvm
焊锡与代码齐飞4 小时前
嵌入式第三十五课!!Linux下的网络编程
linux·运维·服务器·开发语言·网络·学习·算法
省四收割者4 小时前
Go语言入门(10)-数组
数据结构·经验分享·笔记·vscode·算法·golang
lxmyzzs4 小时前
【图像算法 - 21】慧眼识虫:基于深度学习与OpenCV的农田害虫智能识别系统
人工智能·深度学习·opencv·算法·yolo·目标检测·计算机视觉