[Golang] struct配合slice實現迴圈佇列
阿新 • • 發佈:2018-11-22
迴圈佇列
- 特徵
使用的頭尾索引永遠都在底層陣列長度下標範圍內,如佇列長度為10,那麼底層陣列長度為11,index範圍[0,10] - 解決的問題
用非迴圈陣列實現的佇列在底層陣列滿的時候有資料搬移的操作,會影響入隊操作;迴圈陣列可以解決這個問題! - 與同樣用陣列實現的普通佇列的區別
1. 迴圈佇列需要專門佔用陣列的一個位置來作為尾結點標識,這個位置不能填充真實資料,所以實際使用的陣列長度會加一。
2. 迴圈佇列需要一個初始化方法,使用一個預設字元將底層陣列初始化。
3. 迴圈佇列在滿佇列時,在底層沒有資料搬移操作,入隊 T(n)=O(1)。 - Code
package main
import (
"fmt"
"strconv"
)
type LoopQueue struct {
Items []string //利用陣列實現佇列
Head uint16 //頭索引,恆為0
Tail uint16 //尾索引
Len uint16 //限定佇列長度
}
//佇列初始化,將[底層陣列]初始化
func (this *LoopQueue) Init() {
this.Len = this.Len + 1 //因為最後一個位置不能使用,所以len要比宣告的大一
for i:=0;i<int(this.Len) ;i++ {
this.Items = append(this.Items, "")
}
}
//入列
func (this *LoopQueue) Enqueue(v interface{}){
if ((this.Tail+1) % this.Len) == this.Head {
fmt.Println("the queue is full!")
return
}
this.Items[this.Tail] = v.(string)
fmt.Printf("%s enqueued, now length: tail:%s \n",v, this.Tail)
this. Tail = (this.Tail+1) % this.Len
}
//出列
func (this *LoopQueue) Dequeue()interface{}{
if this.Head == this.Tail {
fmt.Println("the queue is empty!")
return nil
}
ret := this.Items[this.Head]
fmt.Printf("Dequeue: %s! the surplus len: head:%s \n", ret, this.Head)
this.Head = (this.Head+1) % this.Len
return ret
}
func main(){
Q := &LoopQueue{Len:10} //設定佇列長度
Q.Init() //初始化佇列
for i:=0;i<12;i++ { //12>10 會提示full
s := strconv.Itoa(i)
Q.Enqueue(s+s+s) //入列(但只能入10個)
}
for i:=0;i<3;i++ {
Q.Dequeue() //出列3個
}
for i:=0;i<12;i++ { //12>10 會提示full
s := strconv.Itoa(i)
Q.Enqueue(s+s+s) //入列12個(但只能入3個)
}
for i:=0;i<12;i++ {
Q.Dequeue() //出列12次(但只能出10個)
}
}
使用這種方式有個問題是,使用佇列前需要呼叫一個初始化方法,且初始化方法時用一個預設字元將底層陣列填滿,實在不是一個好的辦法。讀者如有更好的想法,還請指教。