9.キュー

機能:先入れ先出し、限られた操作のデータ構造。

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
}

 

公開された127元の記事 ウォン称賛24 ビュー130 000 +

おすすめ

転載: blog.csdn.net/Linzhongyilisha/article/details/99720337