【C语言数据结构】链队列

C语言数据结构-链队列 链队列链队列与链表相似,不同的是它具有对列的运算方法,存储结构和链表相同,下面是其结构示意图:这里的*Q类似于链表的头节点*head;它包含两个指向队列节点的指针front和rear;当front和rear都为NULL时队列为空;front指向队列第一个节点,rear指向最后一个节点,当两者指向同一个节点说明队列只有一个节点; 还有不设头指针的链队列表示形式,这里不予说明;下面为上图所示链队列结构 阅读详情

目录

前言

一、链队列

1.链队列头文件及函数声明 

2.初始化

3.结点申请

4.结点释放

5.入队

6.获取队头元素 

5.出栈

 6.清空与销毁

1.清空

2.销毁

8.循环队列源文件及整体函数实现 

总结


前言

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

链队列,实际本身是一个链表,但是因为链表进行尾部元素插入时,其的时间复杂度较大,所以我们在这里使用具有尾指针的单链表,那么我们的入队和出队操作时间复杂度都是O(1),使这种结构的资源消耗降低,如下图所示。

​

同时该链表也失去了对某一位置插入删除的权限。


一、链队列

1.链队列头文件及函数声明 

我们可以新建头文件"lqueue.h"对顺序表函数声明进行保存,方便我们后期查看及使用

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef int ELEM_TYPE;

typedef struct LQueue
{
	ELEM_TYPE data;//数据域
	LQueue* next;//指针域
}LQueue,*PLQueue;

typedef struct Head
{
	PLQueue head;
	PLQueue tail;
}Head,*PHead;

//初始化
void Init_LQueue(PHead pq);

//购买结点
PLQueue BuyNode();

//释放结点
void FreeNode(PLQueue* p);

//入队
void Push(PHead pq, ELEM_TYPE val);

//出队(如果出队成功,则返回出队的值)
bool Pop(PHead pq, ELEM_TYPE* rtval);

//获取队头元素值(如果成功,则返回队头值)
bool Top(PHead pq, ELEM_TYPE* rtval);

//获取有效值个数
int GetSize(PHead pq);

//判空
bool IsEmpty(PHead pq);

//清空
void Clear(PHead pq);

//销毁
void Destroy(PHead pq);

//打印队列
void Show(PHead pq);

2.初始化

我们需要一个链队列的表头来帮助我们储存相关信息:

1.头指针;

2.尾部指针;

那么我们可以定义如下的一个表头结构体:

typedef struct Head
{
	PLQueue head;
	PLQueue tail;
}Head,*PHead;

当然,也有本身的链表结点:

typedef int ELEM_TYPE;

typedef struct LQueue
{
	ELEM_TYPE data;//数据域
	LQueue* next;//指针域
}LQueue,*PLQueue;

接着我们实现一个初始化函数来对表头元素进行初始化:

//初始化
void Init_LQueue(PHead pq)
{
	assert(pq != NULL);
	pq->head = NULL;
	pq->tail = NULL;
}

  完成以上操作,我们就得到一个简单的空的队列,接下来可以对其进行相关操作。

3.结点申请

因为链表的结构特性,我们需要对结点进行多次申请,为了方便进行其他函数操作,并且为了优化代码,我们将结点的申请封装于一个函数。

//购买结点
PLQueue BuyNode()
{
	PLQueue node = (PLQueue)calloc(1, sizeof(LQueue));
	if (node == NULL)
	{
		exit(1);
	}
	return node;
}

4.结点释放

因为链表的结构特性,我们需要对结点进行多次删除,为了方便进行其他函数操作,并且为了优化代码,我们将结点的释放封装于一个函数。

//释放结点
void FreeNode(PLQueue* p)
{
	assert(p != NULL);
	free(*p);
	*p = NULL;
}

5.入队

对数据进行入队,即是直接对队列中链表尾部进行插入操作,即是对链表进行尾插。

注意,因为链队列具有两个指针,所以会出现只有一个元素时,头尾指针指向同一个位置,所以需要对这种情况进行判断。

//入队
void Push(PHead pq, ELEM_TYPE val)
{
	assert(pq != NULL);
	PLQueue newnode = BuyNode();
	newnode->data = val;
	newnode->next = NULL;
	if (pq->head == NULL)
	{
		pq->tail = newnode;
		pq->head = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

6.获取队头元素 

这里与出队基本相同,但是无需删除数据。

rtval是输出参数,帮助获取队头元素。

//获取队头元素值(如果成功,则返回队头值)
bool Top(PHead pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (IsEmpty(pq))
	{
		return false;
	}
	*rtval = pq->head->data;
	return true;
}

5.出栈

rtval是输出参数,帮助获取出队元素。

//出队(如果出队成功,则返回出队的值)
bool Pop(PHead pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (IsEmpty(pq))
	{
		pq->tail = NULL;
		return false;
	}
	PLQueue delnode = pq->head;
	*rtval = delnode->data;
	pq->head = delnode->next;
	FreeNode(&delnode);
	return true;
}

 6.清空与销毁

1.清空

当队列中数据无需使用,我们可以对队列进行清空操作,方法为一直出队;

//清空
void Clear(PHead pq)
{
	assert(pq != NULL);
	ELEM_TYPE rtval = 0;
	while (!IsEmpty(pq))
	{
		Pop(pq, &rtval);
	}
}

2.销毁

销毁相当于进行初始化相反的操作。

//销毁
void Destroy(PHead pq)
{
	Clear(pq);
	pq->front = NULL;
    pq->tail = NULL;
}

8.循环队列源文件及整体函数实现 

源文件:"lqueue.c"

#include "lqueue.h"

//初始化
void Init_LQueue(PHead pq)
{
	assert(pq != NULL);
	pq->head = NULL;
	pq->tail = NULL;
}

//购买结点
PLQueue BuyNode()
{
	PLQueue node = (PLQueue)calloc(1, sizeof(LQueue));
	if (node == NULL)
	{
		exit(1);
	}
	return node;
}

//释放结点
void FreeNode(PLQueue* p)
{
	assert(p != NULL);
	free(*p);
	*p = NULL;
}

//入队
void Push(PHead pq, ELEM_TYPE val)
{
	assert(pq != NULL);
	PLQueue newnode = BuyNode();
	newnode->data = val;
	newnode->next = NULL;
	if (pq->head == NULL)
	{
		pq->tail = newnode;
		pq->head = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

//出队(如果出队成功,则返回出队的值)
bool Pop(PHead pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (IsEmpty(pq))
	{
		pq->tail = NULL;
		return false;
	}
	PLQueue delnode = pq->head;
	*rtval = delnode->data;
	pq->head = delnode->next;
	FreeNode(&delnode);
	return true;
}

//获取队头元素值(如果成功,则返回队头值)
bool Top(PHead pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (IsEmpty(pq))
	{
		return false;
	}
	*rtval = pq->head->data;
	return true;
}

//获取有效值个数
int GetSize(PHead pq)
{
	assert(pq != NULL);
	int num = 0;
	PLQueue node = pq->head;
	while (node != NULL)
	{
		num++;
		node = node->next;
	}
	return num;
}

//判空
bool IsEmpty(PHead pq)
{
	assert(pq != NULL);
	return pq->head == NULL;
}

//清空
void Clear(PHead pq)
{
	assert(pq != NULL);
	ELEM_TYPE rtval = 0;
	while (!IsEmpty(pq))
	{
		Pop(pq, &rtval);
	}
}

//销毁
void Destroy(PHead pq)
{
	Clear(pq);
	pq = NULL;
}

//打印队列
void Show(PHead pq)
{
	assert(pq != NULL);
	PLQueue node = pq->head;
	while (node != NULL)
	{
		printf("%d ", node->data);
		node = node->next;
	}
	printf("\n");
}

总结

以上就是今天要讲解的内容,本文简单介绍了链队列的代码实现。队列在后期处理特殊问题上具有特殊效果。

数据结构,C语言,停车场管理,栈,链队列,带有题目及注释 这还是一个数据结构作业 阅读详情

相关推荐

告别Mac自带终端:iTerm2 + Oh My Zsh 保姆级配置指南(含国内镜像源)

本文提供了一份详细的Mac终端优化指南,涵盖iTerm2、Oh My Zsh和Homebrew的配置流程,特别针对国内用户提供镜像源解决方案。通过安装现代化工具链和优化配置,帮助开发者打造高效、美观的终端工作环境,提升日常开发效率。

weixin_42638178的博客 397

链表栈的基本操作的实现---入栈、出栈、清空

利用链表的结构实现栈的功能---入栈、出栈、清空 代码如下: linkstack.h  链表栈的头文件 #include class Node { public: int data; Node * next; }; class stack { private: Node *head; Node *pcurr; int length; public: stack()

haikuotiankong7的博客 5585

5.4 磁悬浮轴承控制系统仿真:在MATLAB/Simulink中搭建包含功放、传感器模型的闭环系统模型,进行稳定性与动态性能仿真

磁悬浮轴承控制系统仿真方法 摘要:磁悬浮轴承控制系统仿真需建立包含转子动力学、传感器、控制器、功率放大器和电磁执行器的高保真非线性模型。通过MATLAB/Simulink搭建闭环系统,重点建模传感器带宽限制与噪声、功放饱和特性以及电磁力非线性。仿真分析包括时域阶跃响应、扰动抑制测试,频域稳定性分析(伯德图、奈奎斯特图),以及参数摄动下的鲁棒性验证。关键要验证控制算法在非线性因素影响下的稳定性和动态性能,为实际系统实现提供可靠依据。仿真中需特别注意物理量单位一致性和数字控制离散化效应。

技术工作者 1105

数据结构之静态链表的创建(C语言)

什么是静态链表 首先我们让数组的元素都是由两个数据域组成的,data和cur。也就是说,数组的每个下标都对应一个data和一个cur。数据域data,用来存放元素,cur相当于单链表或中的next指针,存放该元素的后继在数组中的下标,我们把cur称为游标。 我们把这种用数组描述的链表叫做静态链表,这种描述方法还有起名叫做游标实现法。 为了方便插入数据,我们通常会把数组建立的大一些,以便有一些空闲空间编译插入是不至于溢出。 /* 线性表的静态链表存储结构 */ #define MAXSIZE 1000 typ

xiangjunyes的博客 1152

问题解决:打开VMware创建的虚拟机,电脑立刻蓝屏并重启

VMware Workstation 与 Device/Credential Guard 不兼容。在禁用 Device/Credenti

weixin_55118477的博客 3万+

论文精读——A Comprehensive Survey of Continual Learning: Theory, Method and Application

为了应对现实世界的动态性,智能系统需要在其整个生命周期中逐步获取、更新、积累并利用知识。这种能力被称为Continue Learning(持续学习)。从广义上讲,持续学习明显受到catastrophic forgetting(灾难性遗忘)的限制,即学习新任务通常会导致旧任务的性能急剧下降。Continue Learning的核心目的有二,其一为(稳定性与可塑性间的权衡),其二为(足够的任务内/任务间泛化能力)。

xsddys的博客 1241

数据结构【队列】

队列的概念 顺序队列 循环队列 顺序循环队列的ADT定义 1、简单结构体定义 2、初始化 3、队列的清空 4、计算队列的长度 5、判断队列是否为空 6、插入新的元素 7、元素的删除 8、遍历输出队列内的所有元素 链队列的ADT定义 1、链队列简单结构体定义 2、初始化链队列 3、判断链队列是否为空 4、清空链队列 5、销毁链队列 6、获取链队列的长度 7、获取链队列的头元素 8、在链队列尾插入新元素 9、删除链队列的头元素 10、遍历链队列中的元素 顺序队列和链式队列的比较

huajian225的博客 3419

4、LTE无人机认证:保障通信安全的新方案

本文针对LTE网络中无人机通信存在的安全风险,提出了一种基于可信第三方GCS的新型认证协议。该协议通过非对称加密和哈希函数保护IMSI等敏感信息,防止身份泄露、中间人攻击、拒绝服务攻击和位置追踪等威胁。利用Scyther工具对协议进行形式化分析,验证了其在机密性、一致性和活性等方面的安全属性,证明该方案能有效提升无人机在LTE网络中的通信安全性与隐私保护能力。

pink的博客 60

C语言写单链表的创建、释放、追加(即总是在最后的位置增加节点)

昨天周末给学妹讲了一些指针的知识,本来我对指针就是似懂非懂的状态,经过昨天一讲,我对指针的学习就更深刻了果然给别人讲课也是学习的一个方法。加上最近复习数据结构,发现我的博客里没有链表的博文,所以趁这时候加上一篇。   在此之前,我们先谈一下我要说的一些基本知识: ①函数参数为什么是双指针?   我们先写一下这么一个程序: # include<stdio.h>vo...

weixin_33739646的博客 1663

软考「系统规划与管理师(第2版)」抱佛脚|案例分析预测

规划类(系统/数据/云)+ 服务过程找错改进 + 风险应急终止三大块各备一套成熟模板,术语统一按第2版新教材口径,案例分析 45 分线的希望就大很多。

软件行业技术文化交流。 71

9.23华为OD机试真题 新系统 - 世界杯徽章换购 (Java/Py/C/C++/Js/Go)

9.23华为OD机试真题 新系统 - 世界杯徽章换购 (Java/Py/C/C++/Js/Go)

算法大师! 1564

C语言内存申请/释放函数,C++内存申请/释放函数

申请堆区空间,并返回一个指向它的指针。是一些C/C++标准在stddef.h中定义的,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数。是需要申请的内存块大小,以字节为单位。申请成功返回指向已分配内存的指针,申请失败返回NULL。printf("申请失败");:申请堆区空间,返回申请空间的地址,并将每个字节初始化为0。为元素个数,为元素大小。:申请成功返回指向已分配内存的指针,申请失败返回NULL。:释放指针指向的堆区空间指针指向的内存:空。

SNAILywu的博客 2065

如何在 UniApp 中接入讯飞语音听写功能 文末附vue3+vue2完整代码

在开发过程中,我遇到了讯飞接口返回空数据的问题。通过仔细检查传送的每一帧数据,我发现问题出在第一帧的配置信息以及 Base64 数据的切片。确保每一帧的数据正确且符合接口要求,问题就能够得到解决。希望这个过程能帮助你在项目中顺利对接讯飞语音识别。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 995

【数据结构】5.1链队列(C语言)

数据结构链队列的概念和实现,内容详细并附有完整代码可供参考

weixin_52811588的博客 316

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

数据结构 - 链队列的实行(C语言)

数据结构-链队列的实现 1 链队列的定义 队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已, 我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点,如下图所示。 空队列时,front和rear都指向头结点,如下图所示。 链队列的结构为: typedef int QElemType; /* QElemType类型根据实际情况而定,这...

weixin_30799995的博客 120

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

六、数据结构基础之链队列C语言实现

1 /* 2 * 六、数据结构基础之链队列 3 * 链队列数据结构: 4 * 限制在表头删除和表尾插入的单链表 5 * --- 2012年4月29日 ---by lee 6 */ 7 8 #ifndef _LINKED_QUEUE_H 9 #define _LINKED_QUEUE_H 10 ...

168

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C语言实现数据结构——链队列

定义 前面学习了栈这种数据结构,我们知道他的特点是数据先进后出。与栈相反,队列的特点时数据先进先出。即first in firsr out,简称FIFO。 队列只允许在表的一端进行数据的插入,在另一端进行数据的删除。这和生活中的排队是一致的,最早进入队列的最先离开。在链表中,允许插入数据的一端叫队尾(rear),允许删除数据的一端叫队头(front)。假设将数据a,b,c,d,e,f输入到一个队列中,那么输入的顺序是a,b,c,d,e,f。输出的顺序也是a,b,c,d,e,f。 基本操作 初始化一个队列

weixin_51408717的博客 1万+

数据结构C语言实现之链队列

#include #include //定义函数结果状态码 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 //定义数据类型 typedef int ElemType ; //定义程序返回状态类型 typedef int State; //链队列结点存储结构 typedef struct _QueueNode {

二手码农的工地 1201

顺序栈与链队列C语言实验报告,数据结构实验二——顺序栈,链栈,循环队列,链队列.doc...

实验报告二实验课名称:数据结构与程序设计实验实验名称:顺序班级:学号:姓名:时间:一、问题描述顺序栈顺序的C语言描述基本运算的算法——置空、、链栈的C语言描述基本运算的算法——置空、、循环队列的C语言描述基本运算的算法——链队列的C语言描述基本运算的算法——顺序栈typedef struct{ //定义栈的数据结构SElemType *base; //栈底...

weixin_30598047的博客 754

数据结构C语言-循环队列、链队

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int status; typedef int ElemType; #define MAXSIZE 100 typedef struct { ElemType base[M...

qq_42845341的博客 220

【C语言入门】数据结构-链队列的代码实现

链队列的代码实现前言代码部分节点定义初始化队列销毁队列入队列出队列总结 前言 由于是给朋友们入门这里的实现是依据严蔚敏版《数据结构》一书中的伪代码进行实现的。主要目的是让朋友 们知道伪代码实现成为正式代码的流程 代码部分 节点定义 //书上代码 typedef struct QNode { QElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct { QueuePtr front; QueuePtr rear;

qq_39625143的博客 1000

顺序队列和链队列-出入队-C语言-数据结构与算法

1-顺序队列入队 2-顺序队列出队 3-链队列入队 4-链队列出队 //**************************************** //数据结构:顺序队列和链队列 //算法:出队和入队 //首次编辑时间:2020/05/28 //最后修改时间:2020/05/29 //**************************************** #include<stdio.h> #include<stdlib.h> #define maxn 20 typ

时光笔墨136的博客 1224

【数据结构】 链队列的基本操作 (C语言版)

【数据结构】 链队列的基本操作 (C语言版)

weixin_56814370的博客 5191

链队列和循环队列(c语言数据结构)

一、链队列: 链队是指采用链式存储结果实现的队列,通常用单链表来表示。一个链队需要两个分别指示队头和队尾的指针才能确定。 代码: #include <stdio.h> #include <malloc.h> //链队列的节点 typedef struct LinkNode{ int data; LinkNode* next; }*LinkNodePtr; //链队列. typedef struct LinkQueue{ LinkNodePtr front; LinkN

awm123453的博客 541

数据结构基础(C语言)———链队列

#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 typedef int ElemType; typedef int status; typedef struct Qnode//链表结点 { ElemType data;//数据域 struct Qnode *next;//指向下一个结点 }Qnode; typedef struct link_queue//链队 { Qnode .

qq_57399201的博客 236
上一篇: 【C语言数据结构】循环队列
下一篇: 【Linux基础】常用目录介绍
W1024201
博客等级 码龄5年 69粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值