当前位置: 首页 > news >正文

专注做一家男人最爱的网站windows优化软件

专注做一家男人最爱的网站,windows优化软件,多巴新城建设管理委员会网站,手机浏览器下载💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ​ 目录 一、引言 🎄队列的概念 🎄为什么要用单链表实现队列 二、单…

   

            💓 博客主页:倔强的石头的CSDN主页 

           📝Gitee主页:倔强的石头的gitee主页

            ⏩ 文章专栏:《数据结构与算法》

                                  期待您的关注

1b7335aca73b41609b7f05d1d366f476.gif

目录

一、引言

🎄队列的概念

🎄为什么要用单链表实现队列

二、单链表前情回顾

三、队列的结构定义

🍃单个元素的结构定义

🍃队列的结构定义

🍃图解单链表与队列的关系

四、队列的接口实现

🌾初始化

🌾销毁

🌾入队列(队尾插入)

🌾出队列(队头删除)

🌾获取队首元素

🌾获取队尾元素

🌾获取队列元素个数

🌾队列判空

五、C语言实现代码

Queue.h   队列头文件

Queue.c    队列实现文件

test.c        main函数测试文件

测试结果

六、应用场景

七、总结


一、引言

🎄队列的概念

队列(Queue)是一种特殊类型的线性数据结构,它遵循特定的操作顺序。队列的基本操作通常是在一端添加元素(称为入队或enqueue),在另一端移除元素(称为出队或dequeue)。这种操作特性使得队列符合“先进先出”(FIFO, First In First Out)的原则。

基本概念

  1. 先进先出(FIFO)原则:这是队列的核心特性。它意味着最早被添加到队列中的元素将是第一个被移除的元素。这个原则确保了数据处理的顺序性。

  2. 队头(Front):队列中第一个被添加的元素位于队头,但它不是永远位于队列的第一个位置,而是指按照入队顺序,最先应该被出队的元素的位置。在出队操作中,总是从队头移除元素。

  3. 队尾(Rear)或队末:新元素总是被添加到队列的这一端。在入队操作中,新元素总是被放置在队尾。

  4. 队列为空:当队列中没有元素时,称队列为空队列。

  5. 队列满:在某些实现中,特别是使用静态数组实现的队列,当队列无法再添加新元素时,称为队列满。但在使用链表实现的队列中,通常不会遇到队列满的情况,因为链表可以动态扩展。

队列提供了一种有效的方式来管理和处理需要按照特定顺序执行的任务或数据项。通过使用队列,可以确保数据项按照它们被接收或生成的顺序进行处理,这是许多应用中非常关键的要求。

🎄为什么要用单链表实现队列

  1. 动态内存分配
    单链表节点是动态分配的,这意味着队列的大小可以根据需要动态地增长和缩小。与静态数组实现的队列不同,单链表队列不需要预先定义最大的容量,从而避免了因队列容量不足而导致的内存溢出问题。

  2. 高效操作
    在单链表队列中,入队(enqueue)操作通常只需要在链表尾部添加一个节点,时间复杂度为O(1)。出队(dequeue)操作也只需要删除链表头部的节点,时间复杂度同样为O(1)。这使得单链表队列在处理大量数据时具有较高的效率。而数组不方便头插或头删,不管将数组的首部当作队首还是队尾都会降低效率

  3. 内存利用率
    单链表队列在添加和删除元素时,只需要分配或释放单个节点的内存,而不需要像数组那样可能需要分配或释放整个数据块的内存。这有助于减少内存碎片,提高内存利用率。另外队列只需要对首尾元素进行操作,带尾指针的单链表已经足够高效的进行插入删除,相比双向链表节省了一半的指针空间。

  4. 灵活性
    单链表队列在结构上相对灵活,可以根据具体需求进行扩展或修改。例如,可以在节点中添加额外的信息以支持更复杂的操作,或者在链表中插入或删除节点以实现特定的功能。

  5. 易于实现
    单链表的基本操作(如添加节点、删除节点等)相对简单,因此使用单链表实现队列也相对容易。这使得初学者能够更容易地理解和实现队列数据结构。

  6. 适应性强
    在实际应用中,队列可能会遇到各种复杂的情况,如并发访问、数据异常等。单链表队列由于其动态性和灵活性,能够较好地适应这些复杂情况。例如,在并发环境下,可以使用锁或其他同步机制来确保队列操作的原子性;在数据异常时,可以通过遍历链表来检查和处理异常情况。

二、单链表前情回顾

参考文章:

【C语言项目实战】使用单链表实现通讯录-CSDN博客

三、队列的结构定义

🍃单个元素的结构定义

  • 数据部分
  • 指向下一个元素的指针next
// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;

🍃队列的结构定义

  • 指向队首元素的指针phead
  • 指向队尾元素的指针ptail
  • 队列的元素个数size
// 队列的结构 
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;

将队列的首尾指针封装成一个结构体,可以方便函数调用,统一接口
另外使用一个整型变量记录元素个数,利于其他函数功能实现

🍃图解单链表与队列的关系

 

四、队列的接口实现

🌾初始化

  • 对形参判空(接收的地址必须是有效的(队列必须存在)
  • 队列的首尾指针初始化为NULL
  • size变量初始化为0
// 初始化队列 
void QueueInit(Queue* q)
{assert(q);//接收的地址必须是有效的(队列必须存在)q->head = q->tail = NULL;q->size = 0;
}

🌾销毁

  • 对形参判空
  • 创建指针循环遍历链表:     每次记录下指针的下一个节点,释放指针指向的节点,指针指向下一个节点
  • 出循环后,将首尾指针指向NULL
  • size置0
// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);while (q->head)//释放所有节点{QNode* next = q->head->next;free(q->head);q->head = next;}q->head = q->tail = NULL;q->size = 0;
}

🌾入队列(队尾插入)

  • 接收两个参数,队列的地址和要插入的数据
  • 首先,对形参指针判空
  • 然后申请新节点,next指针指向NULL,数据部分为要插入的数据
  • 接下来,对空队列和非空队列分别处理:
  • 空队列直接让首尾指针都指向新节点
  • 非空队列:尾指针指向节点的next指针指向新节点,尾指针再指向新节点
  • 完成插入之后,size++
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//判定是否申请成功{perror("newnode error\n");exit(1);}newnode->data = data;newnode->next = NULL;if (q->head == NULL)//对空队列入队的处理{q->head = q->tail = newnode;}else               //对非空队列入队的处理{q->tail->next = newnode;q->tail = newnode;}q->size++;
}

🌾出队列(队头删除)

  • 对形参判空
  • 对队列判空
  • 队首删除分两种情况
  • 队列只有一个元素的情况:    释放该元素空间,首尾指针都指向NULL
  • 队列有多个元素的情况:    记录下第二个节点地址,释放首节点,首指针指向第二个节点
  • 删除完节点之后,size--
// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->head);//队列不能为空if (q->head == q->tail)//对只有一个元素的队列的出队处理{free(q->head);q->head = q->tail = NULL;}else          //对存在多个元素的队列的出队处理{QNode* next = q->head->next;free(q->head);q->head = next;}q->size--;
}

🌾获取队首元素

  • 形参判空
  • 队列判空
  • 返回队首元素的数据
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);//队列不能为空return q->head->data;
}

🌾获取队尾元素

  • 形参判空
  • 队列判空
  • 返回队尾元素的数据
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->head);return q->tail->data;
}

🌾获取队列元素个数

  • 形参判空
  • 返回size
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}

🌾队列判空

  • 形参判空
  • 返回size==0的结果
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}

五、C语言实现代码

Queue.h   队列头文件

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

Queue.c    队列实现文件

#include"Queue.h"// 初始化队列 
void QueueInit(Queue* q)
{assert(q);//接收的地址必须是有效的(队列必须存在)q->head = q->tail = NULL;q->size = 0;
}// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//判定是否申请成功{perror("newnode error\n");exit(1);}newnode->data = data;newnode->next = NULL;if (q->head == NULL)//对空队列入队的处理{q->head = q->tail = newnode;}else               //对非空队列入队的处理{q->tail->next = newnode;q->tail = newnode;}q->size++;
}// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->head);//队列不能为空if (q->head == q->tail)//对只有一个元素的队列的出队处理{free(q->head);q->head = q->tail = NULL;}else          //对存在多个元素的队列的出队处理{QNode* next = q->head->next;free(q->head);q->head = next;}q->size--;
}// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);//队列不能为空return q->head->data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->head);return q->tail->data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);while (q->head)//释放所有节点{QNode* next = q->head->next;free(q->head);q->head = next;}q->head = q->tail = NULL;q->size = 0;
}

test.c        main函数测试文件

#include"Queue.h"void test1()
{Queue Q;QueueInit(&Q);//创建队列并初始化if (QueueEmpty(&Q))printf("队列空\n");elseprintf("队列非空\n");QueuePush(&Q, 1);//队列插入四个数据QueuePush(&Q, 2);QueuePush(&Q, 3);QueuePush(&Q, 4);if (QueueEmpty(&Q))printf("队列空\n");elseprintf("队列非空\n");printf("%d\n", QueueBack(&Q));//取队尾数据while (Q.size)//队列不为空时,每次取队首数据,再出队列{printf("%d ", QueueFront(&Q));QueuePop(&Q);}printf("\n");if (QueueEmpty(&Q))printf("队列空\n");elseprintf("队列非空\n");QueueDestroy(&Q);//队列销毁
}int main()
{test1();return 0;
}

测试结果

六、应用场景

单链表队列的应用场景非常广泛,几乎在所有需要按照特定顺序处理数据的情况下都可以看到它的身影。以下是一些具体的应用场景示例:

  1. 操作系统中的任务调度:在操作系统中,任务(如进程或线程)经常需要按照某种顺序(如优先级、到达时间等)被调度执行。队列可以很好地满足这种需求,确保任务按照预定的顺序被处理。使用单链表实现的队列能够动态地添加和删除任务,非常适合这种场景。

  2. 数据包缓冲处理:在网络通信中,数据包经常需要在一个缓冲区中等待处理。队列结构能够确保数据包按照接收的顺序被处理,避免了乱序问题。单链表队列可以方便地添加新接收的数据包到队尾,并从队头取出数据包进行处理。

  3. 打印机任务队列:在打印多个文档时,打印机会按照接收文档的顺序进行打印。使用队列可以确保文档按照正确的顺序被处理。单链表队列可以动态地添加新的打印任务,并从队头取出任务进行打印。

  4. 事件驱动编程:在事件驱动编程模型中,事件(如用户输入、定时器事件等)会被放入一个事件队列中等待处理。使用队列可以确保事件按照发生的顺序被处理,避免了并发事件导致的混乱。单链表队列可以方便地添加新事件到队尾,并从队头取出事件进行处理。

  5. 游戏开发:在游戏中,经常需要处理大量的游戏对象(如玩家、怪物、子弹等)。使用队列可以确保这些对象按照特定的顺序(如创建顺序、优先级等)被更新或渲染。单链表队列可以动态地添加和删除游戏对象,提高游戏的性能和响应速度。

七、总结

通过本文的介绍,我们了解了如何使用单链表来实现队列,并探讨了其在实际应用中的重要性和应用场景。单链表队列具有动态分配内存、无需预先定义大小等优点,能够方便地添加和删除元素,满足各种按照顺序处理数据的需求。无论是在操作系统、网络通信、打印机任务处理、事件驱动编程还是游戏开发中,我们都可以看到单链表队列的身影。因此,掌握单链表队列的实现原理和应用方法对于程序员来说是非常有必要的。希望本文能够帮助读者更好地理解单链表队列的概念和应用,并在实际项目中灵活运用。


文章转载自:
http://recumbency.c7623.cn
http://namaycush.c7623.cn
http://meant.c7623.cn
http://hecatomb.c7623.cn
http://subdwarf.c7623.cn
http://avoirdupois.c7623.cn
http://gainings.c7623.cn
http://goofus.c7623.cn
http://modernity.c7623.cn
http://sewer.c7623.cn
http://stenographic.c7623.cn
http://luxe.c7623.cn
http://amdea.c7623.cn
http://terminability.c7623.cn
http://adaptability.c7623.cn
http://anaclisis.c7623.cn
http://strigiform.c7623.cn
http://felicitator.c7623.cn
http://gynandromorph.c7623.cn
http://epimere.c7623.cn
http://wordiness.c7623.cn
http://cacodemon.c7623.cn
http://swop.c7623.cn
http://icaaaa.c7623.cn
http://dactylology.c7623.cn
http://sidesplitting.c7623.cn
http://cessionary.c7623.cn
http://antiderivative.c7623.cn
http://schmoll.c7623.cn
http://cowbell.c7623.cn
http://asyntatic.c7623.cn
http://exocarp.c7623.cn
http://shoreline.c7623.cn
http://convocation.c7623.cn
http://reconstruction.c7623.cn
http://gastroscope.c7623.cn
http://horsenapping.c7623.cn
http://corymbose.c7623.cn
http://deductivist.c7623.cn
http://glycolysis.c7623.cn
http://filament.c7623.cn
http://diener.c7623.cn
http://janissary.c7623.cn
http://heighten.c7623.cn
http://thrown.c7623.cn
http://strobila.c7623.cn
http://propinquity.c7623.cn
http://maskless.c7623.cn
http://outjockey.c7623.cn
http://salvolatile.c7623.cn
http://canting.c7623.cn
http://dodecasyllable.c7623.cn
http://mythopoetry.c7623.cn
http://spitzenburg.c7623.cn
http://emanate.c7623.cn
http://cinerary.c7623.cn
http://welder.c7623.cn
http://intropunitive.c7623.cn
http://previable.c7623.cn
http://bobbin.c7623.cn
http://candela.c7623.cn
http://luggage.c7623.cn
http://tinnery.c7623.cn
http://vicuna.c7623.cn
http://permanent.c7623.cn
http://email.c7623.cn
http://communization.c7623.cn
http://muppet.c7623.cn
http://palingenesis.c7623.cn
http://khedive.c7623.cn
http://uplooking.c7623.cn
http://bernie.c7623.cn
http://sasin.c7623.cn
http://astrochronology.c7623.cn
http://antiproton.c7623.cn
http://furosemide.c7623.cn
http://indue.c7623.cn
http://currie.c7623.cn
http://kioto.c7623.cn
http://mount.c7623.cn
http://concinnity.c7623.cn
http://episcopalism.c7623.cn
http://subterraneous.c7623.cn
http://perchloroethylene.c7623.cn
http://tricarpellate.c7623.cn
http://maine.c7623.cn
http://rightpages.c7623.cn
http://bacchae.c7623.cn
http://rearrange.c7623.cn
http://agnosticism.c7623.cn
http://donkeyman.c7623.cn
http://swingletree.c7623.cn
http://seroreaction.c7623.cn
http://demonic.c7623.cn
http://sneakingly.c7623.cn
http://sourish.c7623.cn
http://cosigner.c7623.cn
http://chairwoman.c7623.cn
http://chlamydate.c7623.cn
http://tracheae.c7623.cn
http://www.zhongyajixie.com/news/90671.html

相关文章:

  • 网站租用价格成都业务网络推广平台
  • 日本女做受网站企业邮箱注册申请
  • 做网站如何抓住客户的需求seo培训学校
  • 网站地图导出怎么做新手做销售怎么开发客户
  • 网站建设制作开发 小程序开发定制 软件系统开发百度网站排名优化
  • 个人网站怎么做引流友情链接的网站
  • 杭州号码百事通做网站在线咨询
  • 怎样做ppt建网站seo查询外链
  • 制作网站难不难sem网络营销
  • 网站设置密码怎么破解网页在线秒收录
  • 广州网站制作开发公司百度搜索引擎入口官网
  • 怎么做交易猫假网站百度官方网站网址是多少
  • 个人网站网站建设方案书技成培训网
  • php网站开发参考文献网络营销策略是什么
  • 重庆南川网站制作公司哪家好乐事薯片软文推广
  • wordpress 免费博客平台百度seo怎么收费
  • wordpress两个域名访问不了南昌seo实用技巧
  • 临沂专业网站制作站长统计推荐
  • 济南助企网站建设公司怎么样化学sem是什么意思
  • 工控机做网站服务器360关键词推广
  • 惠州外贸网站建设网站运营
  • 贵阳公司网页网站建设安卓优化
  • 汽车销售网站网络推广 网站制作
  • 重庆微信网站开发公网店推广实训报告
  • 网站怎么做引流微信小程序开发工具
  • 网站mp3播放器代码重庆seo网站排名
  • 打开网站 显示建设中win优化大师有用吗
  • 广西网站建设费用开网店3个月来亏了10万
  • 台州网站制作计划北京seo排名厂家
  • 做企业网站通常哪找素材b站推广入口2023年