一:队列介绍
之前的随笔有提过简单提过队列
①:队列是一个有序的表可以通过数组和链表来表现;
②:遵循先进先出原则
二:非环形队列
①:若使用数组结构存储队列数据,则队列数组的必须声明一个最大队列容量如maxSize,因为队列的输出输入是分别从前后端来处理,因此需要两个变量来记录队列前后端的下标,如front(head)记录前端,rear(tail)记录后端;
②:示意图
③:使用细节
数据存入非环形数组队列时要有两个步骤
③-1:将尾指针往后移:rear++,当front==rear时表明队列为空
③-2:若尾指针rear小于等于队列maxSize-1,则将存入数据rear所在的数组元素中;当rear==maxSize-1时代表队列已满
④:使用举例
package main import ( "fmt" "errors" ) //定义数组队列 type QueueArr struct{ MaxSize int array [5]int front int rear int } //添加 func (this *QueueArr) AddQueue(val int) (err error){ if this.rear+1 == this.MaxSize { return errors.New("队列已满") } this.rear++ this.array[this.rear] = val return } //展示所有 func (this *QueueArr) GetQueue() (err error){ if this.rear == this.front { return errors.New("队列为空") } for i := this.front+1; i <= this.rear; i++ { fmt.Printf("队列第%d=%v\n", i+1, this.array[i]); } return } //获取一个数据 func (this *QueueArr) GetOneQueue() (val int, err error){ if this.rear == this.front { return -1, errors.New("队列为空") } this.front++ val = this.array[this.front] return val, err } func main() { //初始化队列 queueArr := &QueueArr{ MaxSize : 5, front : -1, rear : -1, } //添加三个数据到队列 err := queueArr.AddQueue(0) err = queueArr.AddQueue(1) err = queueArr.AddQueue(2) if err != nil { fmt.Println("添加数据到队列错误:", err) } //读取所有队列数据 err = queueArr.GetQueue() if err != nil { fmt.Println("读取数据到队列错误:", err) } // 联系多次获取单个数据 val, err := queueArr.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println("获取当个数据:", val) } val, err = queueArr.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println("获取当个数据:", val) } val, err = queueArr.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println("获取当个数据:", val) } val, err = queueArr.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println("获取当个数据:", val) } val, err = queueArr.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println("获取当个数据:", val) } } 结果 [ `go run queueArr.go` | done ] 队列第1=0 队列第2=1 队列第3=2 获取当个数据: 0 获取当个数据: 1 获取当个数据: 2 队列为空 队列为空
三:环形数组队列
①:环形数组队列时对非环形数组队列的升级,可以有效的提高资源利用率,而不是一次性使用;
②:和非环形数组不同的是,环形数组需要预留一个空间作为尾索引(约定);
③:使用细节
③-1:(tail+1)%maxSize==head代表队列已满;
③-2:tail==head代表队列为空;
③-3:初始化时tail=0,head=0,不同于非环形队列的-1;
③-4:计算队列还有多少个元素(tail+maxSize-head)%maxSize
④:使用举例
package main import ( "fmt" "errors" ) type CircleQueue struct{ MaxSize int array [5]int head int tail int } //添加 func (this *CircleQueue) AddQueue(val int) (err error){ if (this.tail+1)%this.MaxSize == this.head{ return errors.New("队列已满") } this.array[this.tail] = val this.tail++ return } //展示所有 func (this *CircleQueue) GetQueue() (err error){ if this.head == this.tail { return errors.New("队列为空") } for i := this.head; (i+this.MaxSize)%this.MaxSize < this.tail; i++ { fmt.Printf("队列第%d=%v\n", i, this.array[(i+this.MaxSize)%this.MaxSize]); } return } //获取一个数据 func (this *CircleQueue) GetOneQueue() (val int, err error){ fmt.Println("index=", (this.head+this.MaxSize)%this.MaxSize) if this.tail == this.head { return 0, errors.New("队列为空") } val = this.array[(this.head+this.MaxSize)%this.MaxSize] this.head++ return val, err } func (this *CircleQueue) GetNum() (val int){ return (this.tail+this.MaxSize-this.head)%this.MaxSize } func main() { //初始化环形队列 circleQueue := &CircleQueue{ MaxSize : 5, head : 0, tail : 0, } //添加数据 circleQueue.AddQueue(1) circleQueue.AddQueue(2) circleQueue.AddQueue(3) circleQueue.AddQueue(4) //读取所有数据 circleQueue.GetQueue() //获取4个单个数据 val, err := circleQueue.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println(val) } val, err = circleQueue.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println(val) } val, err = circleQueue.GetOneQueue() if err != nil { fmt.Println(err) }else{ fmt.Println(val) } // 获取有多少个 queueNum := circleQueue.GetNum() fmt.Println("队列数:", queueNum) } 结果 [ `go run circleQueue.go` | done ] 队列第0=1 队列第1=2 队列第2=3 队列第3=4 index= 0 1 index= 1 2 index= 2 3 队列数: 1
原文:https://www.cnblogs.com/louis181214/p/10416833.html