队列(Queue) 是另一种基础且广泛应用的数据结构,它遵循“先进先出”(First In, First Out,简称 FIFO)的原则。
结构特性:
- 队头(Front): 队列中允许删除元素的一端,也就是最早进入队列的元素所在的位置。
- 队尾(Rear/Tail): 队列中允许添加元素的一端,新的元素总是被添加到队尾。
- 操作限制: 元素只能在队尾添加(Enqueue)并在队头删除(Dequeue)。这意味着第一个进入队列的元素也将是最先离开队列的元素。
常见操作:
- Enqueue (入队): 将元素添加到队列的队尾。
- Dequeue (出队): 移除并返回队头的元素。
- Peek/Front: 查看队头元素但不删除。
- IsFull: 检查队列是否已满(对于固定大小的队列)。
- IsEmpty: 判断队列是否为空。
应用场景:
- 操作系统任务调度: 进程或线程等待处理时形成的任务队列。
- 打印作业安排: 多个打印任务排队等候打印机处理。
- 消息传递系统: 消息缓冲区,用于暂时存储发送方发出的消息,直到接收方准备好接收。
- 银行服务柜台: 客户排队等候服务。
实现方式:
- 顺序队列: 可以用数组实现,但需要注意在队列满和空时,队头和队尾的移动可能会造成空间的浪费(循环队列可以避免这个问题)。
- 链式队列: 使用链表实现,队头和队尾节点分别指向链表的首部和尾部,这样可以在理论上无限增长,不受固定空间大小限制。
时间复杂度:
- Enqueue: 如果队列是动态增长的(如链式队列),则入队操作的时间复杂度为 O(1)。
- Dequeue: 与入队操作一样,出队操作在链式队列中也为 O(1)。
- **对于数组实现的循环队列,入队和出队时间复杂度均为 O(1),前提是没有达到数组的边界限制,否则可能需要扩容,此时时间复杂度会上升。
另外,还有双端队列(Deque)等变体,它允许在队列的两端进行插入和删除操作。