package main import ( "errors" "fmt" ) // 队列 // 特征: // 1. 按照元素的添加顺序排序,并且容量固定 // 2. 添加元素,放入末尾 // 3. 移出元素,将最先加入的元素移出 // 4. First In First Out -> FIFO // 实现(头指针 + 尾指针 + 保存元素的元组): // 1. 数组 // 2. 链表 // 思路: // 1. 头指针 + 尾指针 + 保存元素的元组 // 2. 两个方法 Add() Get() // 3. 判空 empty,判满 full // Go 实现队列思路 // 1. queue结构体, buf存储数据, head通过切片下标指向队列头部,tail通过切片下标指向队列尾部,但tail指向的下标不存放元素 // 2. 添加元素使用 Push方法,移动tail指针,如果 tail指针值超过最大值,则重置tail指针指向0, overFlow置为 true // 3. 读取元素使用 Pop方法,移动head指针,如果head指针等于最大值,则重置head指针为0, overflown置为false // 4. 判空:如果 overflown为false且 head = tail时候为空 // 5. 判满: 如果 overflown为false且 tail = maxSize 时为满,如果overflown为true且 tail -1 = head 时候为满 // 难点: 什么时候head 和 tail指针归0,如何空与判满 // queue 模拟队列 type queue struct { // buf 存放元素 buf []int // 一个指向队列的头部,一个指向尾部,但尾部指向的位置不包含元素 head, tail int // 判断头部是否溢出 overflow bool maxSize int } func NewQueue(size int) *queue { return &queue{ buf : make([]int, size + 1), maxSize: size, } } // Push 向队列中添加一个元素 func (q *queue) Push(elem int) (err error) { // 1. 判满 if q.overflow { if q.tail - 1 == q.head { err = errors.New("Q 满") fmt.Println(err) return err } } else { if q.tail == q.maxSize { err = errors.New("Q 满") return err } } // 1. 添加元素,应该头指针指向的下标不存储元素 q.tail ++ q.buf[q.tail - 1] = elem // 如果 q.tail 结果为maxSize则值为0 if q.tail == q.maxSize { q.tail = 0 q.overflow = true } return } // Pop 从队列中移出一个元素 func (q *queue) Pop() (elem int, err error) { // 1. 判空 if !q.overflow { if q.tail == q.head { err = errors.New("Q 空") fmt.Println(err) return -1, err } } // 1. 移出元素,获取头指针指向的元素,并且将头指针加上1 elem = q.buf[q.head] q.head ++ // 2. 如果 q.head 值等于最大值则重置为0 if q.head == q.maxSize { q.head = 0 q.overflow = false } return } // Show 显示队列中的元素 func (q *queue) Show() { data := make([]int, 0 , q.maxSize) if q.overflow { data = append(data, q.buf[:q.tail]...) data = append(data, q.buf[q.head:q.maxSize]...) } else { data = append(data, q.buf[q.head:q.tail]...) } fmt.Println(data) } func main() { q := NewQueue(3) q.Push(3) q.Push(4) q.Push(5) q.Pop() q.Pop() q.Pop() q.Pop() q.Pop() q.Show() q.Pop() q.Show() }