链式队列,队列篇(链式队列的出队入队操作)_链队列的入队和出队-程序员宅基地

技术标签: c++  python  java  c语言  队列  后端  数据结构  

数据结构,队列篇(链式队列)

前言:

上一篇博主简单讲解了顺序队列和循环队列,今天讲解队列最后一篇链式队,链式队在数据结构中用到比较多,用来做一些排队的算法,还有链式队列是也是和链式栈一样采用链表的方式来表现,链式队列针对数据比较灵活的数据比较方便,因为它不像顺序队列一样需要定义最大值,链式队列只需要建立新结点,比较灵活,没有大小限制,只要内存,并且用完了就释放了,对于变动较大的数据很友好。

每日一遍,防止颓废

20200310794875_CsSGzt

1.理解链式队列逻辑,认识核心代码

所谓队列的链式存储结构是用一个线性链表来表示一个队列,队列中每一个元素对应链表中一个链结点,这样的队列简称链接队列。具体地说,把线性链表第1个链结点的指针定义为队头指针front,在链表最后的链结点建立指针rear作为队尾指针,并且限定只能在链头进行删除操作,在链尾进行插入操作,这个线性链表就构成了一个链接队列。另一个与顺序存储结构队列的不同点是,队头指针与队尾指针都是指向实际队头元素与队尾元素所在的链结点。讲人话就是(有着两个指针的单链表,一个指针指向头用来出队,一个指针指向尾用来进队,出队退出条件就是队空,因为是活动的所以不存在存满,除非不能划分内存了

image-20211106111843265

让我们来认识链式队列的核心代码。

typedef struct Node//新结点的类型,就相当于链表
{
	int data;//存放队中的值
	struct Node *next;//用来指向下一个结点
}Queue;
typedef struct queue//用来链队的类型
{
	Queue *front;//链队头指针
	Queue *rear;//链队尾指针
}LinkQueue;
q = (LinkQueue *)malloc(sizeof(LinkQueue)); //分配链队的内存
q->rear =q->front=NULL;//初始队头队尾指针为空
s = (Queue*)malloc(sizeof(Queue));//创建入队结点
s->data = x;///新结点赋值
q->rear->next =s;//入队:尾指针指向新结点
q->rear = s;//入队:改变尾指针的指向,指向新结点
p=q->front;//出队:创建出队结点,把头节点赋值
x =p->data;//出队:出队结点赋值给x,x输出
q->front=q->rear=NULL; //出队:这个是出队结束判断
q->front=q->front->next;//出队:这个头结点已经出队了,改变指向,指向下一个变成新的头结点
free(p);//出队:出队后释放内存

1.1链式队列初始化和简单操作

其实q->rear和q->front就他们相当于两个链表结点,如果你链表学的好,就front就相当于单链表用头插法建立的头指针,rear就相当于单链表用尾插法建立的尾指针,大家联想记忆一下。

void InitQueue(LinkQueue *&q)//q代表引用形参数相当于指针里面指向指针的指针
{
	q = (LinkQueue *)malloc(sizeof(LinkQueue)); //分配链队的内存
	q->rear =q->foont=NULL;//初始队头队尾指针为空
}
int GetHead(LinkQueue *&q,int &x)//获取队头的值
{
	if(q->front==NULL)//判断是不是空队
	{
		return 0;
	}
	x = q->front->data;//将队头的值赋值给x
	return 1;
 } 
 int QueueEmpty(LinkQueue *q)//判断是不是空队
 {
 	if(q->front==NULL) return 1;//是空队返回1
 	else return 0;//不是返回0
 }
 void DestroyQueue(LinkQueue *&q)//销毁队列
{
	Queue *pre = q->front,*p;
	if(pre!=NULL)//判断是不是已经空队
	{
		if(pre==q->rear)//判断队列只剩一个值了,队头和队尾相等
		{
			free(pre);//释放
		}
		else{
			p=pre->next;//p指向头结点的下一个,用来保存头指针的位置(下面代码会把头释放)
			while(p!=NULL)//遍历p的队列结点
			{
				free(pre);//释放头节点
				pre=p;//重新改变头指针指向
				p=p->next;//指向下一个
			}
			free(pre);//释放最后一个,最后一个没释放
		}
		
	}
	free(q);//释放链队指针
}

1.2链式队列进队

链式队列的进队和单链表的建立用尾插法没什么区别

int EnQueue(LinkQueue *&q,int x)//链式队列进队操作
{
	Queue *s;//创建结点指针
	s = (Queue*)malloc(sizeof(Queue));//分配内存
	s->data = x;//给我们的结点赋值
	s->next=NULL;//尾插法,指向空
	if(q->front==NULL)//判断是不是第一个结点
	{
		q->rear=q->front=s;//第一个结点头尾都是指向它
	 } 
	 else//第二个或多个
	 {
	 	q->rear->next =s;//之前指向最后一个结点的尾指针连接新结点,形成链
	 	q->rear = s;//改变尾指针的指向,指向新结点
	 }
	 return 1;
}

1.3链式队列出队

链式队列的进队和单链表的建立用头插法有异曲同工之出,只不过单链表是输入值,队列是输出值

int DeQueue(LinkQueue *&q,int &x)//链式队列出队操作
{
	Queue *p;//创建出队指针
	if(q->front==NULL)//判断是不是空队
	{
		return 0;
	}
	p=q->front;//指向头指针指向的结点
	x =p->data;//获取结点的值并传回主函数
	if(q->rear==q->front)//原队列只有一个结点,出队后队列变空
	{
		q->front=q->rear=NULL; //变为空队
	}
	else{
		q->front=q->front->next;//有两个以上的队列,头指针已经出队,改变头指针的指向
	}
	free(p);//释放
	return 1;
}

1.4链式队列效果演示和整体代码

博主只是对链式队列做了几个简单的操作,用循环进行入队和出队。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
	int data;
	struct Node *next;
}Queue;
typedef struct queue
{
	Queue *front;
	Queue *rear;
}LinkQueue;

void InitQueue(LinkQueue *&q)
{
	q = (LinkQueue *)malloc(sizeof(LinkQueue)); 
	q->rear =q->front=NULL;
}
void DestroyQueue(LinkQueue *&q)
{
	Queue *pre = q->front,*p;
	if(pre!=NULL)
	{
		if(pre==q->rear)
		{
			free(pre);
		}
		else{
			p=pre->next;
			while(p!=NULL)
			{
				free(pre);
				pre=p;
				p=p->next;
			}
			free(pre);
		}
		
	}
	free(q);
}
int EnQueue(LinkQueue *&q,int x)
{
	Queue *s;
	s = (Queue*)malloc(sizeof(Queue));
	s->data = x;
	s->next=NULL;
	if(q->front==NULL)
	{
		q->rear=q->front=s;
	 } 
	 else
	 {
	 	q->rear->next =s;
	 	q->rear = s;
	 }
	 return 1;
}
int DeQueue(LinkQueue *&q,int &x)
{
	Queue *p;
	if(q->front==NULL)
	{
		return 0;
	}
	p=q->front;
	x =p->data;
	if(q->rear==q->front)
	{
		q->front=q->rear=NULL; 
	}
	else{
		q->front=q->front->next;
	}
	free(p);
	return 1;
}
int GetHead(LinkQueue *&q,int &x)
{
	if(q->front==NULL)
	{
		return 0;
	}
	x = q->front->data;
	return 1;
 } 
 int QueueEmpty(LinkQueue *q)
 {
 	if(q->front==NULL) return 1;
 	else return 0;
 }
int main(int argc, char** argv) {
	LinkQueue *lq;
	int e;
	printf("初始化队列\n");
	InitQueue(lq);
	printf("队%s\n",(QueueEmpty(lq)==1?"空":"不空"));
	int i;
	for(i= 1;i<5;i++)
	{
		printf("%d进队\n",i);
		EnQueue(lq,i);
	}
	printf("队%s\n",(QueueEmpty(lq)==1?"空":"不空"));
	GetHead(lq,e);
	printf("队头元素:%d\n",e);
	printf("出队次序");
	while(!QueueEmpty(lq)) 
	{
		DeQueue(lq,e);
		printf("%d",e); 
	}
	printf("\n");
	DestroyQueue(lq);
	return 0;
}

image-20211106121247055

注:大家在跑整体代码的时候,要建立的是cpp的文件,博主不是用到c的文件,大家注意一些,建立cpp文件就是建立C++控制台。

image-20211106121921116

总结:

数据结构线性表的存储博主就差不多就讲完了,我们重点要学好链表,因为栈和队列基本上都是在链表的基础上实现的,所以链表很重要,大家不会的可以看博主之前的链表的文章,我会把链表的博客链接放在下面,大家可以学习一下,创作不易,点赞,关注,评论,收藏。
上一篇:数据结构专升本学习,队列篇(顺序队和循环队列)
上上篇:数据结构专升本学习笔记,线性表链表小节

下一篇:数据结构专升本学习,顺序串篇

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_46104786/article/details/121177311

智能推荐

手把手教你利用爬虫爬网页(Python代码)_python 爬虫 登录网页-程序员宅基地

文章浏览阅读1.3k次,点赞6次,收藏4次。本文主要分为两个部分:一部分是网络爬虫的概述,帮助大家详细了解网络爬虫;另一部分是HTTP请求的Python实现,帮助大家了解Python中实现HTTP请求的各种方式,以便具备编写HTTP网络程序的能力。01网络爬虫概述接下来从网络爬虫的概念、用处与价值和结构等三个方面,让大家对网络爬虫有一个基本的了解。1. 网络爬虫及其应用随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战,网络爬虫应运而生。网络爬虫(又被称为网页蜘蛛、网络机..._python 爬虫 登录网页

基于STM32以及HAL库的MAX30102模块使用+OLED显示(资源下载免费,在博主我的资源下载处)_max30102+oled-程序员宅基地

文章浏览阅读3.4k次,点赞19次,收藏65次。必须要有I2C驱动,为其模块的寄存器写入相应的配置,才能够驱动红灯亮起(里面包括红光以及红外光)。那我们买回模块之后,如何确定模块的好坏,其实可以直接在购买物品的平台上。_max30102+oled

带缓存的Flutter网络请求——RxDio_flutter dio接口缓存-程序员宅基地

文章浏览阅读2.9k次。RxDio是在练习Dio、RxDart、Sql的时候,仿照Android网络请求OkGo做的,只实现了简单的功能,后续有需要再完善。在APP开发中,经常会遇到这样一种情况:在有网络正常的时候,展示网络数据,在网络断开或者网络很差的时候,展示上次正常访问的数据理想的解决方法是,设置几种缓存模式:1、只请求网络2、只访问缓存3、先访问缓存,再请求网络4、没有缓存再请求网络目前仅支持GE..._flutter dio接口缓存

基于广播星历的北斗定位解算原理(基于C语言和MATLAB实现)_卫星位置解算-程序员宅基地

文章浏览阅读2.3k次,点赞32次,收藏53次。本文先用C语言解算卫星位置,再用MATLAB绘出卫星三维坐标图。本篇博客所使用的资料和文件都是网络上公开发表且可以找到的资料文件。_卫星位置解算

Vue面试题-程序员宅基地

文章浏览阅读158次。ViewModel提供双向数据绑定把View和Model连接起来,他们之间的同步是自动的,不需要人为的干涉,所以我们只需要关注业务逻辑,不需要操作DOM,同时也不需要关注数据的状态问题,因为他是MVVM统一管理。当我们在组件中访问 Vuex 中的状态时,Vue.js 的响应式系统会建立依赖关系,并将组件与状态属性之间的关联记录下来。代码分割和异步加载:将页面按需拆分成多个模块,通过使用路由懒加载或动态导入组件的方式,使得页面初始化时只加载必要的代码,延迟加载其他非必要的模块,从而加快首屏渲染速度。

【新手科研指南5】深度学习代码怎么读-小白阶段性思路(以手写数字识别应用为例)_深度学习程序怎么读-程序员宅基地

文章浏览阅读6.2k次,点赞6次,收藏26次。我是一个深度学习代码小白,请你用中文写上注释,能让我能轻松理解下面这段代码。注意包含所有函数、调用和参数的注释。以同样的python代码块样式返回你写的代码给我。代码看累了,就看《动手学深度学习》文档:基于PyTorch框架,从底层函数实现基础功能,再到框架的高级功能。努力上路的小白一枚,麻烦路过的大佬指导一二,同时希望能和大家交流学习~争取更新学习这个文档的专栏,记录学习过程。量身定做了一套话术hhh,亲身测试还不错。这个感觉更浅一点儿,之后复习看吧。20天吃掉那只Pytorch。_深度学习程序怎么读

随便推点

kindle安卓更新固件(已经装过安卓系统)_kindle enter updating mode-程序员宅基地

文章浏览阅读4.7w次,点赞2次,收藏14次。(http://182.254.232.41/download/update/update.170822/doc/3.%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0.html)1根据机型下载安卓固件,在电脑上解压缩固件,《kindle.xxxxxx.zip》入门版499《kpw2.xxxxxx.zip》Paperwhite二代《kpw3.xxxx_kindle enter updating mode

idea与vue+ElementUI搭建前后端分离的CRUD_elementplus vue idea-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏15次。idea与vue+ElementUI搭建前后端分离的CRUD_elementplus vue idea

html+css+js图片加载失败设置默认图片_js图片加载失败事件-程序员宅基地

文章浏览阅读468次。【代码】html+css+js图片加载失败设置默认图片。_js图片加载失败事件

AES-GCM加密算法的简单介绍_aes gcm-程序员宅基地

文章浏览阅读1.5w次,点赞6次,收藏54次。一.什么是AES加密?常见的加密主要分为两类:对称加密和非对称加密,AES加密就是对称加密的一种,即加密和解密使用相同的一把密钥。它的全称是Advanced Encryption Standard(高级加密标准),主要是用来取代DES加密算法,目前已经被全世界广泛采用,各大处理器厂商也在各自的CPU中,集成了专门的AES指令集,从而在硬件层面提升了AES加解密的速度。具体加密过程:十分钟读懂AES加密算法二.AES加密基本构成1.对称加密相关概念明文P(plainText):未经加密的数据密钥K_aes gcm

静态表的查找操作实验(数据结构C语言版)_用顺序查找方法味例设计一个有关静态查找表的简历,查找等基本操作的演示程序,-程序员宅基地

静态表的查找操作实现了顺序查找、二分查找和索引查找。实验结果显示元素的位置或未找到元素。

C#生成CSV文件_c# 生成csv-程序员宅基地

文章浏览阅读1.2w次,点赞5次,收藏27次。编程中,通常需要将数据进行保存,保存为CSV文件,代码如下://写CSV文件 /// &lt;summary&gt; /// Write CSV File /// &lt;/summary&gt; /// &lt;param name="fileName"&gt;&lt;/param&gt; /// &lt;pa..._c# 生成csv

推荐文章

热门文章

相关标签