Go数据结构之数组队列
一:队列介绍
之前的随笔有提过简单提过队列
①:队列是一个有序的表可以通过数组和链表来表现;
②:遵循先进先出原则
二:非环形队列
①:若使用数组结构存储队列数据,则队列数组的必须声明一个最大队列容量如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("队列已满")
}
// if(this.tail == this.MaxSize){
// this.tail = 0
// }
this.array[this.tail] = val
this.tail = (this.tail+1)%this.MaxSize
return
}
//展示所有
func (this *CircleQueue) GetQueue() (err error){
if this.head == this.tail {
return errors.New("队列为空")
}
for i := this.head; i != this.tail; i = (i+1)%this.MaxSize {
fmt.Printf("队列第%d=%v\n", i, this.array[i]);
}
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 = (this.head+1)%this.MaxSize
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.AddQueue(5)
//读取所有数据
circleQueue.GetQueue()
//获取4个单个数据
val, err := circleQueue.GetOneQueue()
if err != nil {
fmt.Println(err)
}else{
fmt.Println(val)
}
err = circleQueue.AddQueue(5)
if err != nil {
fmt.Println(err)
}
circleQueue.GetQueue()
} 结果 [ `go run circleQueue.go` | done ] 队列第0=1
队列第1=2
队列第2=3
队列第3=4
index= 0
1
队列第1=2
队列第2=3
队列第3=4
队列第4=5

浙公网安备 33010602011771号