目录
一、队列初印象:生活与代码中的排队现象
在日常生活里,排队是我们再熟悉不过的场景。比如在超市结账时,大家自觉排成一列,先来的顾客先完成结账离开,后来的顾客则在队尾耐心等待。又比如在火车站检票口,乘客们按照到达的先后顺序依次检票进站 ,这些都是现实生活中的排队场景,体现了一种 “先来先服务” 的原则。
在编程的世界中,也存在着类似的概念,那就是队列(Queue)。队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作 ,这种操作规则使得队列具有 “先进先出”(First In First Out,FIFO)的特性。就好像现实生活中的排队一样,先进入队列的数据元素会先被处理,而后进入的则需等待。
队列在编程领域中有着举足轻重的地位,它被广泛应用于各种场景。例如在操作系统中,任务调度就会用到队列,操作系统会将待执行的任务按照一定顺序放入队列,CPU 则按照队列的顺序依次取出任务并执行 ,确保各个任务都能得到合理的处理。在网络通信中,数据的传输也会借助队列,当发送方发送数据时,数据会先进入发送队列,然后按照顺序逐个被发送出去;接收方收到数据后,会将数据放入接收队列,再依次进行处理,这样可以保证数据的有序传输,避免数据混乱。
二、顺序队列:队列的数组实现之道
在了解了队列的基本概念后,接下来我们深入探讨队列的一种重要实现方式 —— 顺序队列。顺序队列是基于数组来实现队列的存储 ,它就像是一个固定大小的数组,按照顺序依次存放队列中的元素。
为了实现队列的先进先出特性,顺序队列引入了两个重要的指针:头指针(front)和尾指针(rear) 。头指针指向队列的第一个元素,也就是下一个将要出队的元素;尾指针则指向队列的最后一个元素的下一个位置,即新元素将要插入的位置。当队列初始化时,头指针和尾指针通常都指向数组的起始位置,也就是 0。
当进行入队操作时,新元素会被放置在尾指针所指向的位置,然后尾指针向前移动一位 ,以此表示队列中增加了一个元素。例如,假设我们有一个初始状态为空的顺序队列,此时头指针和尾指针都指向 0。当元素 1 入队时,它会被存放在数组下标为 0 的位置,然后尾指针移动到下标为 1 的位置;接着元素 2 入队,存放在下标 1 的位置,尾指针再移动到下标 2 的位置 ,以此类推。
而出队操作则是取出头指针所指向的元素,然后头指针向前移动一位 ,表示该元素已出队,队列中减少了一个元素。比如,在上述队列中,当进行出队操作时,首先取出头指针指向的元素 1,然后头指针从 0 移动到 1,此时头指针指向元素 2,下一次出队就会取出元素 2。
不过,顺序队列在实际应用中存在一些问题。由于它是基于数组实现的,数组的大小是固定的,当队列中的元素不断增加,尾指针可能会移动到数组的末尾,导致无法继续入队 ,即使此时数组前面可能还有空闲的位置,这种现象被称为 “假溢出”。为了解决这个问题,就引入了循环队列的概念,将数组看作是一个环形结构,当尾指针到达数组末尾时,再继续移动就会回到数组的起始位置 ,这样可以充分利用数组的空间,提高队列的存储效率。
三、基本操作大揭秘:代码实操展身手
为了更直观地理解顺序队列的工作原理,下面我们通过 Python 代码来实现顺序队列的基本操作 ,包括初始化、入队、出队、判空、获取队头元素等。
class Queue:
def __init__(self, max_size):
self.max_size = max_size
self.queue = [None] * max_size
self.front = 0
self.rear = 0
def is_empty(self):
return self.front == self.rear
def