定义
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列本身是有序列表,数组或链表实现,若使用数组的结构来存储队列的数据,则队列数组的声明如上图, 其中 maxSize 是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变,如图所示:
队列增加数据时候 rear增加;队列消费数据时候 front改变。
应用场景
- 操作系统管道通信
- 并发容器:阻塞队列、并发队列。
- “生产者 - 消费者”、“发布 - 订阅”模型。
- 优先级队列:最大/小堆方法解决 topK 问题。
- 树相关:层序遍历、高度。
- 图相关:广度优先遍历。
基本结构和操作
type Queue struct {
buff []int //队列的的数据存储在数组上
maxsize int //队列最大容量
front int //队列头索引,不包括自己(队列头索引值-1)
rear int //队列尾索引
}
入队列
//
// Push
// @Description: 压入队列
// @Author: maxwell.ke
// @time 2022-10-25 22:58:58
// @receiver q
// @param n
// @return error
//
func (q *Queue) Push(n int) error {
if q.rear == q.maxsize-1 {
if q.front == -1 { //头尾都到头了
return fmt.Errorf("队列已满,PUSH失败")
} else { 尾都到头了,头有空,则重置front
q.front = -1
q.rear = len(q.buff) - 1
}
}
q.rear++
q.buff = append(q.buff, n)
return nil
}
出队列
//
// Pop
// @Description: 出队列
// @Author: maxwell.ke
// @time 2022-10-25 23:14:20
// @receiver q
// @return n
// @return err
//
func (q *Queue) Pop() (n int, err error) {
if len(q.buff) == 0 {
return 0, fmt.Errorf("空队列,POP失败")
}
n = q.buff[0]
q.buff = q.buff[1:]
q.front++
return n, nil
}
遍历
//
// List
// @Description: 队列遍历
// @Author: maxwell.ke
// @time 2022-10-25 23:13:10
// @receiver q
// @return error
//
func (q *Queue) List() error {
if len(q.buff) == 0 {
return fmt.Errorf("空队列")
}
for i := 0; i < q.maxsize; i++ {
if i > q.front && i <= q.rear {
fmt.Println(q.buff[i-q.front-1])
} else {
fmt.Println("nil")
}
}
fmt.Println()
return nil
}
汇总
package main
import "fmt"
type Queue struct {
buff []int //队列的的数据存储在数组上
maxsize int //队列最大容量
front int //队列头索引,不包括自己(队列头索引值-1)
rear int //队列尾索引
}
//
// Push
// @Description: 压入队列
// @Author: maxwell.ke
// @time 2022-10-25 22:58:58
// @receiver q
// @param n
// @return error
//
func (q *Queue) Push(n int) error {
if q.rear == q.maxsize-1 {
if q.front == -1 { //头尾都到头了
return fmt.Errorf("队列已满,PUSH失败")
} else { 尾都到头了,头有空,则重置front
q.front = -1
q.rear = len(q.buff) - 1
}
}
q.rear++
q.buff = append(q.buff, n)
return nil
}
//
// Pop
// @Description: 出队列
// @Author: maxwell.ke
// @time 2022-10-25 23:14:20
// @receiver q
// @return n
// @return err
//
func (q *Queue) Pop() (n int, err error) {
if len(q.buff) == 0 {
return 0, fmt.Errorf("空队列,POP失败")
}
n = q.buff[0]
q.buff = q.buff[1:]
q.front++
return n, nil
}
//
// List
// @Description: 队列遍历
// @Author: maxwell.ke
// @time 2022-10-25 23:13:10
// @receiver q
// @return error
//
func (q *Queue) List() error {
if len(q.buff) == 0 {
return fmt.Errorf("空队列")
}
for i := 0; i < q.maxsize; i++ {
if i > q.front && i <= q.rear {
fmt.Println(q.buff[i-q.front-1])
} else {
fmt.Println("nil")
}
}
fmt.Println()
return nil
}
func main() {
var aQueue = Queue{
buff: make([]int, 0, 5),
maxsize: 5,
front: -1,
rear: -1,
}
aQueue.Push(3)
aQueue.Push(6)
aQueue.Push(5)
aQueue.List()
aQueue.Pop()
aQueue.Pop()
aQueue.List()
aQueue.Push(1)
aQueue.Push(2)
aQueue.Push(3)
aQueue.List()
}