Go数据结构之数组队列

312 阅读7分钟
原文链接: www.cnblogs.com

一:队列介绍

之前的随笔有提过简单提过队列

①:队列是一个有序的表可以通过数组和链表来表现;

②:遵循先进先出原则

二:非环形队列

①:若使用数组结构存储队列数据,则队列数组的必须声明一个最大队列容量如maxSize,因为队列的输出输入是分别从前后端来处理,因此需要两个变量来记录队列前后端的下标,如front(head)记录前端,rear(tail)记录后端;

②:示意图

③:使用细节

数据存入非环形数组队列时要有两个步骤

③-1:将尾指针往后移:rear++,当front==rear时表明队列为空

③-2:若尾指针rear小于等于队列maxSize-1,则将存入数据rear所在的数组元素中;当rear==maxSize-1时代表队列已满

④:使用举例

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 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

④:使用举例

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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