环形队列是有序存储,遵循先入先出原则
高效利用内存空间,节省资源
案例
先存三个数据,队列MaxSize = 4
再存一个,就满了,因为预留一个位置
此时,取出数据到提示为空
在空队列的基础上继续添加数据
由此可见,循环队列,可以重复利用空间.
-
代码:
1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 ) 8 9 /* 10 CircleQueue 环形队列结构体 11 12 MaxSiz 最大长度 13 14 Array 真正存储数据的地方 15 16 Head 队首 17 18 Tail 队尾 19 */ 20 type CircleQueue struct { 21 MaxSize int 22 Array [4]int 23 Head int 24 Tail int 25 } 26 27 //PushValue 推入数据 28 func (cq *CircleQueue) PushValue(value int) (err error) { 29 30 /* 如果队列以满 */ 31 if cq.IsFull() { 32 return errors.New("环形队列以满,无法在推入数据") 33 } 34 35 /* 添加 数据 到 队尾指向的 位置 */ 36 cq.Array[cq.Tail] = value 37 cq.Tail = (cq.Tail + 1) % cq.MaxSize 38 return 39 } 40 41 //PopValue 弹出数据 42 func (cq *CircleQueue) PopValue() (value int, err error) { 43 if cq.IsNull() { 44 return 0, errors.New("环形队列以空,无法在弹出数据") 45 } 46 47 /* 取出 环形队列指向的 队首的数据*/ 48 value = cq.Array[cq.Head] 49 cq.Head = (cq.Head + 1) % cq.MaxSize 50 return 51 52 } 53 54 //PrintCircleQueue 输出环形队列 55 func (cq *CircleQueue) PrintCircleQueue() { 56 57 size := cq.GetDataSize() 58 if size == 0 { 59 fmt.Println("环形队列为空") 60 } 61 62 tempHead := cq.Head 63 64 for i := 0; i < size; i++ { 65 fmt.Printf("CircleQueue [%v] = %v ", tempHead, cq.Array[tempHead]) 66 tempHead = (tempHead + 1) % cq.MaxSize 67 } 68 69 } 70 71 //IsFull 是否为满 72 func (cq *CircleQueue) IsFull() bool { 73 return (cq.Tail+1)%cq.MaxSize == cq.Head 74 } 75 76 //IsNull 是否为空 77 func (cq *CircleQueue) IsNull() bool { 78 return cq.Tail == cq.Head 79 } 80 81 //GetDataSize 获取数据长度 82 func (cq *CircleQueue) GetDataSize() int { 83 return (cq.Tail + cq.MaxSize - cq.Head) % cq.MaxSize 84 } 85 func main() { 86 /* 实例化 队列结构体 并初始化*/ 87 q := &CircleQueue{ 88 MaxSize: 4, 89 Head: 0, 90 Tail: 0, 91 } 92 var key int 93 var value int 94 for { 95 fmt.Println( 96 ` 97 1. Add 添加队列 98 2. Get 获取队列 99 3. Print 输出队列 100 4. exit 退出 101 请输入 (1-4) 102 `) 103 fmt.Scanln(&key) 104 switch key { 105 case 1: 106 fmt.Println("请输入要添加的value") 107 fmt.Scanln(&value) 108 err := q.PushValue(value) 109 if err != nil { 110 fmt.Println(err.Error()) 111 } else { 112 fmt.Printf("将 %v 推入 环形队列成功! ", value) 113 } 114 case 2: 115 v, err := q.PopValue() 116 if err != nil { 117 fmt.Println(err.Error()) 118 } else { 119 fmt.Printf("从环形队列中获取到了: %v ", v) 120 } 121 case 3: 122 q.PrintCircleQueue() 123 case 4: 124 os.Exit(0) 125 default: 126 fmt.Println("输入有误,请输入(1-4)") 127 } 128 } 129 }