C语言实现链式队列
链式队列,简称"链队列",即使用链表实现的队列存储结构。
链式队列的实现思想同顺序队列类似,只需创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素,如下图所示:
所示为链式队列的初始状态,此时队列中没有存储任何数据元素,因此 top 和 rear 指针都同时指向头节点。
在创建链式队列时,强烈建议初学者创建一个带有头节点的链表,这样实现链式队列会更简单。
由此,我们可以编写出创建链式队列的 C 语言实现代码为:
//链表中的节点结构
typedef struct QNode{
int data;
struct QNode * next;
}QNode;
//创建链式队列的函数
QNode * initQueue(){
//创建一个头节点
QNode * queue=(QNode*)malloc(sizeof(QNode));
//对头节点进行初始化
queue->next=NULL;
return queue;
}
链式队列数据入队
链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:
- 将该数据元素用节点包裹,例如新节点名称为 elem;
- 与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=elem;
- 最后移动 rear 指针指向该新节点,即 rear=elem;
由此,新节点就入队成功了。
例如,在上图的基础上,我们依次将{1,2,3}依次入队,各个数据元素入队的过程如下图所示:
数据元素入链式队列的 C 语言实现代码为:
QNode* enQueue(QNode * rear,int data){
//1、用节点包裹入队元素
QNode * enElem=(QNode*)malloc(sizeof(QNode));
enElem->data=data;
enElem->next=NULL;
//2、新节点与rear节点建立逻辑关系
rear->next=enElem;
//3、rear指向新节点
rear=enElem;
//返回新的rear,为后续新元素入队做准备
return rear;
}
链式队列数据出队
当链式队列中,有数据元素需要出队时,按照 “先进先出” 的原则,只需将存储该数据的节点以及它之前入队的元素节点按照原则依次出队即可。这里,我们先学习如何将队头元素出队。
链式队列中队头元素出队,需要做以下 3 步操作:
- 通过 top 指针直接找到队头节点,创建一个新指针 p 指向此即将出队的节点;
- 将 p 节点(即要出队的队头节点)从链表中摘除;
- 释放节点 p,回收其所占的内存空间;
例如,在上图2b) 的基础上,我们将元素 1 和 2 出队,则操作过程如下图所示:
链式队列中队头元素出队的 C 语言实现代码为:
void DeQueue(QNode * top,QNode * rear){
if (top->next==NULL) {
printf("队列为空");
return ;
}
// 1、
QNode * p=top->next;
printf("%d",p->data);
top->next=p->next;
if (rear==p) {
rear=top;
}
free(p);
}
注意,将队头元素做出队操作时,需提前判断队列中是否还有元素,如果没有,要提示用户无法做出队操作,保证程序的健壮性。
链式队列的长度
链式队列的长度,只需要设置一个移动指针,由队列头部移动直至到队列尾部,来达到计数的效果。
//队列的长度
int QueueLength(QNode * top)
{
int length=0;
QNode * pMove = top;
if(pMove->next==NULL){//头指针指向空,长度为0
return length;
}
while (pMove->next !=NULL) {//头指针不为空,移动指针计算长度
pMove = pMove->next;
length++;
}
return length;
}
链式队列的打印
链式队列的打印,实际上也就是一个链表的遍历过程。
void printQueue(QNode * top)
{
QNode * pMove = top->next;
if(pMove->next==NULL){
printf("该队列为空!\n");
}
while (pMove!=NULL) {
printf("%d ",pMove->data);
pMove = pMove->next;
}
printf("\n");
}
总结
通过学习链式队列最基本的数据入队和出队操作,我们可以就实际问题,对以上代码做适当的修改。
前面在学习顺序队列时,由于顺序表的局限性,我们在顺序队列中实现数据入队和出队的基础上,又对实现代码做了改进,令其能够充分利用数组中的空间。链式队列就不需要考虑空间利用的问题,因为链式队列本身就是实时申请空间。因此,这可以算作是链式队列相比顺序队列的一个优势。
这里给出链式队列入队和出队的完整 C 语言代码为:
#include <stdio.h>
#include <stdlib.h>
//链表中的节点结构
typedef struct QNode{
int data;
struct QNode * next;
}QNode;
//创建链式队列的函数
QNode * initQueue(){
//创建一个头节点
QNode * queue=(QNode*)malloc(sizeof(QNode));
//对头节点进行初始化
queue->next=NULL;
return queue;
}
QNode* enQueue(QNode * rear,int data){
QNode * enElem=(QNode*)malloc(sizeof(QNode));
enElem->data=data;
enElem->next=NULL;
//使用尾插法向链队列中添加数据元素
rear->next=enElem;
rear=enElem;
return rear;
}
QNode* DeQueue(QNode * top,QNode * rear){
if (top->next==NULL) {
printf("\n队列为空");
return rear;
}
QNode * p=top->next;
printf("出队的元素是:%d \n",p->data);
top->next=p->next;
if (rear==p) {
rear=top;
}
free(p);
return rear;
}
//队列的长度
int QueueLength(QNode * top)
{
int length=0;
QNode * pMove = top;
if(pMove->next==NULL){//头指针指向空,长度为0
return length;
}
while (pMove->next !=NULL) {//头指针不为空,移动指针计算长度
pMove = pMove->next;
length++;
}
return length;
}
void printQueue(QNode * top)
{
QNode * pMove = top->next;
if(pMove->next==NULL){
printf("该队列为空!\n");
}
while (pMove!=NULL) {
printf("%d ",pMove->data);
pMove = pMove->next;
}
printf("\n");
}
int main() {
QNode * queue,*top,*rear;
queue=top=rear=initQueue();//创建头结点
//向链队列中添加结点,使用尾插法添加的同时,队尾指针需要指向链表的最后一个元素
for(int i=0;i<10;i++)
{
rear = enQueue(rear, i+1);
}
printQueue(top);
printf("队列的长度为:%d\n",QueueLength(top));
//入队完成,所有数据元素开始出队列
rear=DeQueue(top, rear);
rear=DeQueue(top, rear);
return 0;
}
程序运行结果为:
1 2 3 4 5 6 7 8 9 10
队列的长度为:10
出队的元素是:1
出队的元素是:2
以上就是本次给大家分享的C语言实现链式队列,如今作为大学生的我,也开始受网课的折磨了,在家上网课的感觉比在学校还要累。每天都在上课,写作业,所以一直更新文章也比较少。需要了解其他的数据结构的知识的,可以访问个人博客,我们一起交流分享啊!
C语言实现链式队列的更多相关文章
- C语言数据结构-链式队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
1.数据结构-链式队列的实现-C语言 typedef struct QNode { int data; struct QNode *next; }QNode,*QueuePtr; typedef st ...
- 队列(链式队列)----C语言
链式队列----用链表实现,链式队列就是一个操作受限的单向链表,如果读者了解单向链表的建立过程,那理解链式队列就很容易了,先回顾一下单向链表的建立过程 (不熟悉单向链表的可以先看看另一片随笔,再回来看 ...
- C语言链表全操作(增,删,改,查,逆序,递增排序,递减排序,链式队列,链式栈)
一,数据结构——链表全操作: 链表形式: 其中,每个节点(Node)是一个结构体,这个结构体包含数据域,指针域,数据域用来存放数据,指针域则用来指向下一个节点: 特别说明:对于单链表,每个节点(Nod ...
- 顺序队列与链式队列--C语言实现
关于队列,因为我自己在平时使用不多,所以在这里直接将队列的两种存储方式放在一起,作为一篇随笔,这两份代码均可直接运行,亲测.注释写的应该也算比较详细了,就不过多的解释了 顺序队列 #include&l ...
- C ~ 链式队列与循环队列
此处的链式与循环队列可以应用于BFS和树的层序遍历.下面是对其结构和基本操作的程序描述. 1.循环队列 解决循环队列的队空和队满的方法: [1].增加一个参数count,用来记录数组中当前 ...
- 数据结构Java实现07----队列:顺序队列&顺序循环队列、链式队列、顺序优先队列
一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其 ...
- 循环队列和链式队列(C++实现)
循环队列: 1.循环队列中判断队空的方法是判断front==rear,队满的方法是判断front=(rear+1)%maxSize.(我曾经想过为什么不用一个length表示队长,当length==m ...
- 利用链式队列(带头节点)解决银行业务队列简单模拟问题(c++)-- 数据结构
题目: 7-1 银行业务队列简单模拟 (30 分) 设某银行有A.B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客 ...
- c++实验5 顺序/链式队列
链式队列及循环队列 1.循环队列的实现(请采用模板类及模板函数实现) [实现提示] 同时可参见教材p65-p67页的ADT描述及算法实现及ppt)函数.类名称等可自定义,部分变量请加上学号后3位.也可 ...
随机推荐
- [BUG]微信浏览器 iOS input 失焦页面不回弹
描述 ios13. ios中,input唤醒软键盘后,body整体会向上滚动,如果input框输入完成确定后,如果页面在最底部则不回弹,导致fixed布局实际效果上移,fixed布局内按钮点不到. 如 ...
- 使用Github Packages功能上传nuget包到Github
前几天微软收购npm的新闻对于软粉来收很是振奋.微软收购npm很可能是为了加强Github Packages.目前Github,Typescript,VSCode,npm这些开源社区的重磅工具全部都在 ...
- nmap加载nse脚本在内网渗透中的使用-下
smb-ls.nse 列举共享目录内的文件,配合smb-enum-share使用nmap -p 445 <ip> --script smb-ls --script-args 'share= ...
- 洛谷2212Watering the Fields S 最小生成树
题目链接:https://www.luogu.com.cn/problem/P2212 几乎是Kruskal裸题,但是建n*(n-1)条边给我T了俩点,后来我发现只要C(n,2)条边就可以,因为假设( ...
- Nginx做负载均衡的几种轮询策略
集群环境为了解决单点无法支撑高并发的情况,集群采用多台服务器提供服务,一般在集群中使用nginx 将来自客户端的请求转发给服务器端 nginx负载均衡可用提高网站的吞吐量,缓解单台服务器的压力. 一. ...
- LightOj 1197 Help Hanzo 区间素数筛
题意: 给定一个区间a,b,a-b>=100000,1<=a<=b<=231,求出给定a,b区间内的素数的个数 区间素数筛 (a+i-1)/ ii向上取整,当a为 i 的整数倍 ...
- 【python系统学习11】循环语句里的F4
循环语句里的F4 深入了解下四个新语句,分别是:continue.break.pass.else以及他们搭配for.while循环等语句时,所产生的化学反应. else 由于continue.brea ...
- 高性能RabbitMQ
1,什么是RabbitMq RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件).RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开 ...
- .NET 5 中的正则引擎性能改进(翻译)
前言 System.Text.RegularExpressions 命名空间已经在 .NET 中使用了多年,一直追溯到 .NET Framework 1.1.它在 .NET 实施本身的数百个位置中使用 ...
- 图的广度优先遍历(bfs)
广度优先遍历: 1.将起点s 放入队列Q(访问) 2.只要Q不为空,就循环执行下列处理 (1)从Q取出顶点u 进行访问(访问结束) (2)将与u 相邻的未访问顶点v 放入Q, 同时将d[v]更新为d[ ...