队列的特性是先进先出(FIFO),也就是说,最先进入队列的元素将最先被处理,而最后进入队列的元素将最后被处理。队列可以用于许多不同的应用程序,例如在操作系统中进行进程调度,网络路由中传输数据包,或在游戏中管理玩家的行动。
什么是队列
队列是一种基本的数据结构,在计算机科学中有广泛的应用。队列的基本概念是先进先出(FIFO),它的操作类似于现实生活中排队等待的过程。最先进入队列的元素将最先被处理,而最后进入队列的元素将最后被处理。
队列的应用
队列可以用于许多不同的应用程序,例如
- 在操作系统中进行进程调度,网络路由中传输数据包,或在游戏中管理玩家的行动。
- 在操作系统中,进程被排列在一个队列中,按照它们被提交的顺序来运行。
- 在网络路由中,数据包被传输到目的地,按照它们被接收的顺序来处理。
- 在游戏中,玩家的行动被加入到一个队列中,以确保每个玩家按照他们的顺序进行操作。
另外一类比较有名的程序叫做:消息队列。可以作为削峰平谷的中间件来使用。
基本操作
队列通常具有两个基本操作:入队和出队。入队操作将一个元素添加到队列的末尾,而出队操作则将队列的第一个元素弹出并返回。队列还可以支持其他操作,例如查看队列的第一个元素,检查队列是否为空,或清空整个队列。这些操作使得队列成为一种非常灵活和有用的数据结构。
代码实现
队列可以使用数组或链表实现。数组实现的队列通常具有固定的大小,而链表实现的队列可以支持动态大小调整。
这里还是只提供数组的实现:
package main
import "fmt"
type Queue struct {
items []int
}
func (q *Queue) Enqueue(item int) {
q.items = append(q.items, item)
}
func (q *Queue) Dequeue() int {
if len(q.items) == 0 {
panic("Queue is empty")
}
item := q.items[0]
q.items = q.items[1:]
return item
}
func (q *Queue) IsEmpty() bool {
return len(q.items) == 0
}
func main() {
q := Queue{}
q.Enqueue(1)
q.Enqueue(2)
q.Enqueue(3)
fmt.Println(q.Dequeue()) // 1
fmt.Println(q.Dequeue()) // 2
fmt.Println(q.IsEmpty()) // false
fmt.Println(q.Dequeue()) // 3
fmt.Println(q.IsEmpty()) // true
}
队列与二叉树
在对二叉树进行层次遍历的时候,常常使用队列做为辅助。
一般的思路是:
先将一层(最开始只有根节点)的数据加入队列中,然后循环当前的队列的长度 len 次。
每次将队首元素节点弹出队列,取出该节点的值加入结果中,然后将该节点的左右子节点加入队列。
循环完 len 次后,一层的节点已经全部遍历完毕,剩下在队列中的节点均为下一层的节点。
继续进行 len 次的循环直到遍历完所有的节点。
这里给出一道Leetcode题目和AC代码:
原题:
AC代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func levelOrder(root *TreeNode) [][]int {
// 如果队列为空,则直接返回
if root == nil {
return [][]int{}
}
results := make([][]int, 0)
q := make([]*TreeNode, 1)
// 将根节点加入队列
q[0] = root
for len(q) > 0 {
length := len(q)
// 新建表示一层的节点的数组
result := make([]int, 0, length)
// 执行 length 次
for i := 0; i < length; i++ {
// 弹出队首节点
node := q[0]
q = q[1:]
// 将该节点的值加入数组
result = append(result, node.Val)
// 将该节点的左右非空子节点加入队列
if node.Left != nil {
q = append(q, node.Left)
}
if node.Right != nil {
q = append(q, node.Right)
}
}
// 执行完 length 之后,数组中为该层所有的节点值,队列中为该层的下一层所有的节点值
results = append(results, result)
}
return results
}