1. 程式人生 > 程式設計 >golang環形佇列實現程式碼示例

golang環形佇列實現程式碼示例

Summary

  • 什麼是環形佇列
  • 實現環形佇列圖示過程
  • golang版本程式碼實現過程
  • 參考全部程式碼

什麼是環形佇列

在一個指定大小的數組裡迴圈寫入資料,借用二個指標分別實現入隊標記與出隊標記.也體現了指標的大好用處,請深入體會.大有裨益.

如圖所示,一個環形佇列.含有二個指標:佇列頭指標,佇列尾指標.

實現環形佇列圖示過程

初始化一個數組大小為6的環形佇列,頭指標front=0,尾指標rear=0,剛好front=rear =0的狀態,表示環形佇列為空.


2.向環形佇列裡插入1個元素,則rear指標移動一格,front=0,rear=1


3.繼續新增a2,a3,a4,a5元素,rear指標指到末尾處,reat=5


4.如果再繼續新增a6元素,則rear=6,大於陣列大小,發生陣列溢位.


5.如上圖所示新增a6時,rear指標發生溢位.我們使用一個小技巧,當rear=6時與陣列大小6進行取模,(rear+1) % maxLen,讓rear指標回到開始處rear=0,問題來了,我們無法判斷陣列是否滿?因為初始化時front=rear=0,現在陣列滿也是front=rear=0


6.解決以上問題有三種辦法,我們採用第3種方法實現.

使用第3種方法: 即當(rear+1) % maxLen == front時,判斷環形陣列滿,則無法新增元素

golang版程式碼實現過程

a. 定義環形資料結構

type CycleQueue struct {
 data []interface{} //儲存空間
 front int      //前指標,前指標負責彈出資料移動
 rear int      //尾指標,後指標負責新增資料移動
 cap  int      //設定切片最大容量 
}

b.初始化環形佇列

func NewCycleQueue(cap int) *CycleQueue {
 return &CycleQueue{
  data: make([]interface{},cap),cap:  cap,front: 0,rear: 0,}
}

c. 入隊操作

//入隊操作
//判斷佇列是否隊滿,隊滿則不允許新增資料
func (q *CycleQueue) Push(data interface{}) bool {
 //check queue is full
 if (q.rear+1)%q.cap == q.front { //佇列已滿時,不執行入隊操作
  return false
 }
 q.data[q.rear] = data     //將元素放入佇列尾部
 q.rear = (q.rear + 1) % q.cap //尾部元素指向下一個空間位置,取模運算保證了索引不越界(餘數一定小於除數)
 return true
}

d.出隊操作

//出隊操作
//需要考慮: 隊隊為空沒有資料返回了
func (q *CycleQueue) Pop() interface{} {
 if q.rear == q.front {
  return nil
 }
 data := q.data[q.front]
 q.data[q.front] = nil
 q.front = (q.front + 1) % q.cap
 return data
}

e:求當前的環形佇列長度

//因為是迴圈佇列,後指標減去前指標 加上最大值,然後與最大值 取餘
func (q *CycleQueue) QueueLength() int {
 return (q.rear - q.front + q.cap) % q.cap
}

參考全部程式碼

github

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。