golang数组实现环形队列

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_45604257/article/details/102728162

思路:

  1. 将数组看成是一个环形的(通过取模的方式来实现)

  2. 什么时候表示队列满 (tail+1)%maxSize==head

  3. 当tail==head时表示队列为空

  4. 初始化时,tail=0,head=0

  5. 统计该队列有多少个元素 (tail+maxSize-head)%maxSize

  6. tail在队列尾部,不包含最后的元素(见下面的‘注意’),head指向队首并且含队首元素

**注意:**尾索引的下一个为头索引时,表示队列满,所以要将队列容量空出一个作为约定,即在判断队列是否满的时候是(tail+1)%maxSize==head(满)
代码如下:

package main

import (
	"errors"
	"fmt"
	"os"
)

//使用一个结构体管理环形队列
type circleQueue struct {
	maxSize int    //
	array   [5]int //数组
	head    int    //指向队列队首
	tail    int    //指向队列队尾
}

//入队列
func (this *circleQueue) push(val int) (err error) {
	if this.isFull() {
		return errors.New("队列满了")
	}
	//this.tail在队列尾部,但是不包含最后的元素
	this.array[this.tail] = val
	this.tail = (this.tail + 1) % this.maxSize
	return
}

//出队列
func (this *circleQueue) pop() (val int, err error) {
	if this.isEmpty() {
		return 0, errors.New("队列是空的")
	}
	//取出,head指向队首并且含队首元素

	this.head = (this.head + 1) % this.maxSize
	return
}

//显示队列
func (this *circleQueue) listQueue() {
	fmt.Println("环形队列情况如下")
	//取出当前队列有多少个元素
	size := this.size()
	if size == 0 {
		fmt.Println("队列为空")
	}
	//设计一个辅助变量,指向head
	tempHead := this.head
	for i := 0; i < size; i++ {
		fmt.Printf("arr[%d]=%d\t", tempHead, this.array[tempHead])
		tempHead = (tempHead + 1) % this.maxSize
	}
	fmt.Println()
}

//判断环形队列为满
func (this *circleQueue) isFull() bool {
	return (this.tail+1)%this.maxSize == this.head
}

//判断队列是否为空
func (this *circleQueue) isEmpty() bool {
	return this.tail == this.head
}

//环形队列有多少个元素
func (this *circleQueue) size() int {
	//重要:一定要看
	//环形队列,head在不停的增长,快出去的时候加了一个maxSize,又拐回来,所以tail
	//某个情况下,自然值是小于head的,因此tail需要+maxSize再-head,然后再对maxSize取模
	return (this.tail + this.maxSize - this.head) % this.maxSize
}
func main() {
	//初始化环形队列
	queue := &circleQueue{
		maxSize: 5,
		head:    0,
		tail:    0,
	}

	var key string
	var val int
	for {
		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.push(val)
			if err != nil {
				fmt.Println(err.Error())
			} else {
				fmt.Println("加入队列OK")

			}
		case "get":
			val, err := queue.pop()
			if err != nil {
				fmt.Println(err.Error())
			} else {
				fmt.Println("从队列中取出了", val)
			}

			fmt.Println("get")
		case "show":
			queue.listQueue()
		case "exit":
			os.Exit(0)

		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_45604257/article/details/102728162