【数据结构】队列

本文介绍了数据结构中的队列,包括队列的基本概念、特点和实际应用。详细讲解了顺序队列和链式队列的实现方式,以及各自的优缺点,如顺序队列的空间浪费和循环队列解决的假溢出问题。同时提到了链式队列在处理队列为空和队列操作上的灵活性。


http://data.biancheng.net/view/300.html

栈和队列不要混淆,栈是一端开口、另一端封口,元素入栈和出栈遵循“先进后出”原则;
队列是两端都开口,但元素只能从一端进,从另一端出,且进出队列遵循“先进先出”的原则。

定义

类似于现实中排队时的队列(队尾进,队头出),插入元素的一端称为队尾,删除(取出)元素的一端称为队头。分别对应于入队和出队操作。

队列的特点

1、元素只能从队列的一端进入,从另一端出去
通常,我们将元素进入队列的一端称为“队尾”,进入队列的过程称为“入队”;将元素从队列中出去的一端称为“队头”,出队列的过程称为“出队”。

2、队列中各个元素的进出必须遵循“先进先出”的原则,即最先入队的元素必须最先出队。

3、队列也不能直接访问位于中间的数据,必须通过出队操作将目标数据变成首位后才能访问。

队列的实际应用

解决 CPU 资源的竞争问题

对于一台计算机来说,CPU 通常只有 1 个,是非常重要的资源。如果在很短的时间内,有多个程序向操作系统申请使用 CPU,就会出现竞争 CPU 资源的现象。不同的操作系统,解决这一问题的方法是不一样的,有一种方法就用到了队列这种存储结构。

假设在某段时间里,有 A、B、C 三个程序向操作系统申请 CPU 资源,操作系统会根据它们的申请次序,将它们排成一个队列。根据“先进先出”原则,最先进队列的程序出队列,并获得 CPU 的使用权。待该程序执行完或者使用 CPU 一段时间后,操作系统会将 CPU 资源分配给下一个出队的程序,以此类推。如果该程序在获得 CPU 资源的时间段内没有执行完,则只能重新入队,等待操作系统再次将 CPU 资源分配给它。

顺序队列

顺序队列详解(C语言实现)

实现

我们采用 C 语言中的数组实现顺序表。既然用顺序表模拟实现队列,必然要先定义一个足够大的数组。不仅如此,为了遵守队列中数据从 “队尾进,队头出” 且 “先进先出” 的规则,还需要定义两个变量(top 和 rear)分别记录队头和队尾的具体位置,

缺点

在元素不断入队、出队的过程中,顺序队列会整体向顺序表的尾部移动。整个实现方案存在的缺陷是:

  1. 顺序队列前面的空闲空间无法再被使用,会造成空间浪费;
  2. 当顺序队列移动至顺序表尾部时,即便顺序表中有空闲空间,新元素也无法成功入队,我们习惯将这种现象称为“假溢出”。

循环队列

顺序队列的 “假溢出” 问题:队列的存储空间未满,却发生了溢出。比如尾指针现在虽然已经指向了最后一个位置的下一位置,但是之前队头也删除了一些元素,那么头指针经历若干次的加1之后,留出了很多空位置,但是顺序队列还在傻乎乎的以为再有元素入队就溢出呢!肯定不合理。故循环队列诞生!

所以解决"假溢出"的办法就是后面满了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。将新元素插入到第一个位置上,入队和出队仍按先进先出的原则进行,操作效率高,空间利用率高。

缺点

判空的问题,因为仅凭 front = rear 不能判定循环队列是空还是满。

链式队列

队列
使用链表形式来实现队列。

使用单向链表来实现链式队列,链式队列中存储front和rear即可。

为了方便实现,链式队列中的front表示链表的头节点,而front的next才表示队头

在链式队列中,不需要考虑队列是否已满,只要内存足够就可以一直分配空间。而当front和rear都指向头节点的时候,则表示此时队列为空。

入队时移动rear指向最后一个元素即可。

出队时,不需要移动front指针,只需将其next指针指向下一个next元素即可。q->front->next = q->front->next->next; 但是需要考虑一种特殊情况,即当队列中只剩下一个元素时,还需要使rear指针重新指向头节点。

顺序队列和链式队列的比较

顺序队列是用数组实现的,首指针在出队的时候移动,尾指针在入队的时候移动,需要考虑队列为空和队列为满的两种情况
链式队列是用链表实现的,首指针不移动始终指向头节点,尾指针在入队的时候移动,只考虑队列为空的情况(不用考虑满是因为链表长度在程序运行过程中可以不断增加,只要存储空间够malloc就能申请内存空间来存放节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值