機能:先入れ先出し、限られた操作のデータ構造。
2つの基本操作:
エンキュー()、データをキューの最後に置きます。
デキュー()、キューの先頭から要素を取得します。
順次キュー:配列の実装、制限されたキューサイズ。
連鎖キュー:無期限にキューに入れることができる連鎖実装では、キューで待機し、応答時間が長くなる可能性があります。
キューには2つのポインターが必要です。1つはチームの頭を指すヘッドポインター、もう1つはチームの尾を指すテールポインターです。
デキュー操作を2回呼び出した後、キュー内のヘッドポインターは添え字2の位置を指し、テールポインターは依然として添え字4の位置を指します。
ノンストップエンキューおよびデキュー操作では、ヘッドとテールは引き続き後方に移動します。
キューのテールポインターが配列の右端に移動した後、新しいデータがキューに入ると、データを先頭と末尾の間で位置0に移動し、全体として配列の末尾に移動できます。
リンクリストに基づくキューの実装方法
循環キュー:
空のチームと満員のチームを決定するための条件を決定します。
チームがいっぱいになると、(尾+ 1)%n =頭。
キューが空の場合、this.head == this.tail
ブロックされたキュー:キューは空で、データはブロックされています。キューがいっぱいになると、挿入されたデータがブロックされます。
「生産者-消費者モデル」
並行キュー:スレッドセーフキュー
最も単純な実装:enqueue()、dequeue()メソッドのロック
配列ベースの循環キューは、CASアトミック操作を使用して、非常に効率的な並行キューを実現できます。これが、循環キューがチェーンキューよりも広く使用されている理由です。
配列に基づく:
package _queue
import "fmt"
type ArrayQueue struct {
q []interface{}
capacity int
head int
tail int
}
func NewArrayQueue(n int) *ArrayQueue {
return &ArrayQueue{make([]interface{}, n), n, 0, 0}
}
func (this *ArrayQueue) EnQueue(v interface{}) bool {
if this.tail == this.capacity {
return false
}
this.q[this.tail] = v
this.tail++
return true
}
func (this *ArrayQueue) DeQueue() interface{} {
if this.head == this.tail {
return nil
}
v := this.q[this.head]
this.head++
return v
}
func (this *ArrayQueue) String() string {
if this.head == this.tail {
return "empty queue"
}
result := "head"
for i := this.head; i <= this.tail-1; i++ {
result += fmt.Sprintf("<-%+v", this.q[i])
}
result += "<-tail"
return result
}
リンクされたリストに基づく:
package _queue
import "fmt"
type ListNode struct {
val interface{}
next *ListNode
}
type LinkedListQueue struct {
head *ListNode
tail *ListNode
length int
}
func NewLinkedListQueue() *LinkedListQueue {
return &LinkedListQueue{nil, nil, 0}
}
func (this *LinkedListQueue) EnQueue(v interface{}) {
node := &ListNode{v, nil}
if nil == this.tail {
this.tail = node
this.head = node
} else {
this.tail.next = node
this.tail = node
}
this.length++
}
func (this *LinkedListQueue) DeQueue() interface{} {
if this.head == nil {
return nil
}
v := this.head.val
this.head = this.head.next
this.length--
return v
}
func (this *LinkedListQueue) String() string {
if this.head == nil {
return "empty queue"
}
result := "head<-"
for cur := this.head; cur != nil; cur = cur.next {
result += fmt.Sprintf("<-%+v", cur.val)
}
result += "<-tail"
return result
}
循環キューの実装:
package _queue
import "fmt"
type CircularQueue struct {
q []interface{}
capacity int
head int
tail int
}
func NewCircularQueue(n int) *CircularQueue {
if n == 0 {
return nil
}
return &CircularQueue{make([]interface{}, n), n, 0, 0}
}
/*
队列空条件:head==tail为true
*/
func (this *CircularQueue) IsEmpty() bool {
if this.head == this.tail {
return true
}
return false
}
/*
队列满条件:(tail+1)%capacity==head为true
*/
func (this *CircularQueue) IsFull() bool {
if this.head == (this.tail+1)%this.capacity {
return true
}
return false
}
func (this *CircularQueue) EnQueue(v interface{}) bool {
if this.IsFull() {
return false
}
this.q[this.tail] = v
this.tail = (this.tail + 1) % this.capacity
return true
}
func (this *CircularQueue) DeQueue() interface{} {
if this.IsEmpty() {
return nil
}
v := this.q[this.head]
this.head = (this.head + 1) % this.capacity
return v
}
func (this *CircularQueue) String() string {
if this.IsEmpty() {
return "empty queue"
}
result := "head"
var i = this.head
for true {
result += fmt.Sprintf("<-%+v", this.q[i])
i = (i + 1) % this.capacity
if i == this.tail {
break
}
}
result += "<-tail"
return result
}