基本介绍
- 队列是一个有序列表,可以用数组或是链表来实现。
- 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
栈: 先入后出(弹夹)
队首 , 队尾

数组模拟环形队列
使用数组实现简单队列的思路
非环
- 创建一个数组arrary,是作为队列的一个字段
- front初始化为-1
- rear, 表示队列尾部,初始化为-1
- 完成队列的基本查找
AddQueue // 加入数据到队列
GetQueue // 从队列取出数据
ShowQueue // 显示队列
代码实现(非环队列)
// 数组模拟队列// 非环队列package mainimport ("errors""fmt""os")/*1. 创建一个数组arrary,是作为队列的一个字段2. front初始化为-13. rear, 表示队列尾部,初始化为-14. 完成队列的基本查找AddQueue // 加入数据到队列GetQueue // 从队列取出数据ShowQueue // 显示队列*/type Queue struct {maxSize intarray [4]int // 数组模拟队列front int // 队列首(下标index), 不包含队首的元素rear int // 队列尾(下标index)}// 添加数据到队列 - 入队列func (que *Queue) AddQueue(val int) (err error) {// 先判断队列是否已满if que.rear == que.maxSize-1 {return errors.New("queue full")}que.rear++ // rear 后移que.array[que.rear] = valfmt.Println("front = ", que.front, "rear = ", que.rear, "array = ", que.array)return}// 显示队列func (que *Queue) ShowQueue() {fmt.Println("显示队列: ")fmt.Println("front = ", que.front, "rear = ", que.rear, "array = ", que.array)// front初始值是 -1, 不包含队首的元素for i := que.front + 1; i <= que.rear; i++ {fmt.Printf("array[%d] = %d\n", i, que.array[i])}fmt.Println()}// 出队列func (que *Queue) GetQueue() (val int, err error) {// 判断队列是否是空if que.rear == que.front {return -1, errors.New("queue empty")}que.front++val = que.array[que.front]que.array[que.front] = 0fmt.Println("front = ", que.front, "rear = ", que.rear, "array = ", que.array)return val, err}func main() {queue := &Queue{maxSize: 4,front: -1,rear: -1,}var key stringvar val intfor {fmt.Println("1. 输入 add 表示添加数据到队列")fmt.Println("2. 输入 get 表示从队列中获取数据")fmt.Println("3. 输入 show 表示显示队列")fmt.Println("4. 输入 exit 表示退出")fmt.Scanln(&key)switch key {case "add":fmt.Println("请输入要入队列的数")fmt.Scanln(&val)err := queue.AddQueue(val)if err == nil {fmt.Println("加入队列成功")} else {fmt.Println(err.Error())}case "get":val, err := queue.GetQueue()if err == nil {fmt.Println("取到的值:", val)} else {fmt.Println(err.Error())}case "show":queue.ShowQueue()case "exit":os.Exit(0)default:fmt.Println("输入有误,请重新输入")}}}/*getfront = 2 rear = 3 array = [0 0 0 4]取到的值: 31. 输入 add 表示添加数据到队列2. 输入 get 表示从队列中获取数据3. 输入 show 表示显示队列4. 输入 exit 表示退出getfront = 3 rear = 3 array = [0 0 0 0]取到的值: 41. 输入 add 表示添加数据到队列2. 输入 get 表示从队列中获取数据3. 输入 show 表示显示队列4. 输入 exit 表示退出getqueue empty*/
数组模拟环形队列
分析思路:
什么时候表示队列满
(tail + 1) % maxSize = head
tail == head 表示空
- 初始化时, tail = 0 head = 0
- 环形实现: tail = (tail + 1) % maxSize, head = (head + 1) % maxSize
核心思想:到达队尾的时候,通过 加1取模 的方式回到队首
- 怎么统计该队列有多少个元素
(tail + maxSize - head ) % maxSize
代码实现
// 数组模拟环形队列(有缺口)package mainimport ("errors""fmt""os")/*分析思路:1. 什么时候表示队列满(tail + 1) % maxSize == head2. tail == head 表示空3. 初始化时, tail = 0 head = 04. 怎么统计该队列有多少个元素(tail + maxSize - head ) % maxSize*/type CircleQueue struct {maxSize intarray [5]inthead int // 队首, 初始 0tail int // 队尾, 初始 0}// 判断环形队列是否已满func (que *CircleQueue) IsFull() bool {fmt.Println("IsFull --- head", que.head, "tail", que.tail)return (que.tail+1)%que.maxSize == que.head}// 判断环形队列是否为空func (que *CircleQueue) IsEmpty() bool {return que.tail == que.head}// 环形队列所有元素func (que *CircleQueue) Size() int {return (que.tail + que.maxSize - que.head) % que.maxSize}// 入队列func (que *CircleQueue) Push(val int) (err error) {// 先判断队列是否已满if que.IsFull() {return errors.New("CircleQueue full")}que.array[que.tail] = valfmt.Println("head = ", que.head, "tail = ", que.tail, "array = ", que.array)// que.tail = (que.tail + 1) % que.maxSizeque.tail = (que.tail + 1) % len(que.array)// que.tail++ // tail 后移return}// 出队列func (que *CircleQueue) Pop() (val int, err error) {// 判断队列是否是空if que.IsEmpty() {return 0, errors.New("CircleQueue empty")}val = que.array[que.head]que.array[que.head] = 0fmt.Println("Pop --- head = ", que.head, "tail = ", que.tail, "array = ", que.array)que.head = (que.head + 1) % que.maxSizereturn val, err}// 显示队列func (que *CircleQueue) ShowQueue() {fmt.Println("显示队列: ")size := que.Size()if size == 0 {fmt.Println("队列为空")}tempHead := que.headfor i := 0; i < size; i++ {fmt.Printf("arr[%d]=%d\t", tempHead, que.array[tempHead])tempHead = (tempHead + 1) % que.maxSize}fmt.Println()fmt.Println("head = ", que.head, "tail = ", que.tail, "array = ", que.array)fmt.Println()}func main() {circleQueue := &CircleQueue{maxSize: 5,head: 0,tail: 0,}var key stringvar val intfor {fmt.Println("1. 输入 add 表示添加数据到队列")fmt.Println("2. 输入 get 表示从队列中获取数据")fmt.Println("3. 输入 show 表示显示队列")fmt.Println("4. 输入 exit 表示退出")fmt.Scanln(&key)switch key {case "add":fmt.Println("请输入要入队列的数")fmt.Scanln(&val)err := circleQueue.Push(val)if err == nil {fmt.Println("加入队列成功")} else {fmt.Println(err.Error())}case "get":fmt.Println("取出")val, err := circleQueue.Pop()if err == nil {fmt.Println("取到的值:", val)} else {fmt.Println(err.Error())}case "show":circleQueue.ShowQueue()case "exit":os.Exit(0)default:fmt.Println("输入有误,请重新输入")}}}/*get取出Pop --- head = 1 tail = 0 array = [0 0 3 4 5]取到的值: 21. 输入 add 表示添加数据到队列2. 输入 get 表示从队列中获取数据3. 输入 show 表示显示队列4. 输入 exit 表示退出add请输入要入队列的数6IsFull --- head 2 tail 0head = 2 tail = 0 array = [6 0 3 4 5]加入队列成功1. 输入 add 表示添加数据到队列2. 输入 get 表示从队列中获取数据3. 输入 show 表示显示队列4. 输入 exit 表示退出show显示队列:arr[2]=3 arr[3]=4 arr[4]=5 arr[0]=6head = 2 tail = 1 array = [6 0 3 4 5]*/

