1. 程式人生 > 實用技巧 >GoLang 資料結構-環形佇列

GoLang 資料結構-環形佇列

  • 環形佇列是有序儲存,遵循先入先出原則

  • 高效利用記憶體空間,節省資源

  • 案例

  • 先存三個資料,佇列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\n", 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 推入 環形佇列成功!\n", 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\n", 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 }
View Code