使用Golang建立優先佇列的程式
優先佇列是一種佇列,其中元素被分配了優先順序,優先順序較高的元素比優先順序較低的元素先彈出。
在本文中,我們將編寫Golang程式來建立優先佇列。它們可以使用堆、切片、樹等實現,並用於執行諸如將元素推入佇列和從佇列中移除元素等操作。
語法
func make ([] type, size, capacity)
Go語言中的make函式用於建立陣列/對映,它接受要建立的變數的型別、大小和容量作為引數。
func append(slice, element_1, element_2…, element_N) []T
append函式用於向陣列切片新增值。它接受多個引數。第一個引數是要向其新增值的陣列,後跟要新增的值。然後,該函式返回包含所有值的最終陣列切片。
func len(v Type) int
len()函式用於獲取任何引數的長度。它接受一個引數作為要查詢其長度的資料型別變數,並返回一個整數,即該變數的長度。
演算法
步驟 1 - 建立一個名為Item的結構體,其中包含三個欄位:value(專案的值,型別為字串)、priority(專案的優先順序,型別為整數)和index(專案的索引,型別為整數)。
步驟 2 - 然後,建立一個名為PriorityQueue的型別,作為Item的切片,並帶有指向它的指標。
步驟 3 - 實現Len()方法、Less()方法、Swap()方法、Push()方法、Pop()方法。
步驟 4 - 最後,實現update方法來更新佇列元素的優先順序和值。
步驟 5 - 在main函式中,建立一個名為piq的空優先佇列,型別為PriorityQueue。
步驟 6 - 在此步驟中,使用heap包中的Push()函式將專案推入優先佇列,並使用PriorityQueue的Update()方法更新專案的優先順序。
步驟 7 - 在這裡,從heap包中的優先佇列中彈出專案,直到佇列為空。列印每個彈出專案的value和priority。
示例 1
在本例中,我們將編寫一個Golang程式,使用二叉堆建立優先佇列。專案的切片將被建立為指向它的指標。
package main import ( "container/heap" "fmt" ) type Item struct { value string priority int index int } type PriorityQueue []*Item func (piq PriorityQueue) Len() int { return len(piq) } func (piq PriorityQueue) Less(i, j int) bool { return piq[i].priority > piq[j].priority } func (piq PriorityQueue) Swap(i, j int) { piq[i], piq[j] = piq[j], piq[i] piq[i].index = i piq[j].index = j } func (piq *PriorityQueue) Push(x interface{}) { n := len(*piq) item := x.(*Item) item.index = n *piq = append(*piq, item) } func (piq *PriorityQueue) Pop() interface{} { old := *piq n := len(old) item := old[n-1] item.index = -1 *piq = old[0 : n-1] return item } func (piq *PriorityQueue) Update(item *Item, value string, priority int) { item.value = value item.priority = priority heap.Fix(piq, item.index) } func main() { piq := make(PriorityQueue, 0) heap.Push(&piq, &Item{value: "Item 1", priority: 30}) heap.Push(&piq, &Item{value: "Item 2", priority: 10}) heap.Push(&piq, &Item{value: "Item 3", priority: 20}) item := piq[2] piq.Update(item, item.value, 40) for piq.Len() > 0 { item := heap.Pop(&piq).(*Item) fmt.Printf("Value: %s, Priority: %d\n", item.value, item.priority) } }
輸出
Value: Item 3, Priority: 40 Value: Item 1, Priority: 30 Value: Item 2, Priority: 10
示例 2
在本例中,我們將編寫一個Golang程式,使用Item結構體的切片來實現優先佇列。
package main import ( "fmt" ) type Item struct { value string priority int } type PriorityQueue []Item func (piq PriorityQueue) Len() int { return len(piq) } func (piq PriorityQueue) Less(i, j int) bool { return piq[i].priority > piq[j].priority } func (piq PriorityQueue) Swap(i, j int) { piq[i], piq[j] = piq[j], piq[i] } func (piq *PriorityQueue) Push(x interface{}) { item := x.(Item) *piq = append(*piq, item) } func (piq *PriorityQueue) Pop() interface{} { old := *piq n := len(old) item := old[n-1] *piq = old[0 : n-1] return item } func main() { piq := make(PriorityQueue, 0) piq.Push(Item{value: "Item 1", priority: 30}) piq.Push(Item{value: "Item 2", priority: 10}) piq.Push(Item{value: "Item 3", priority: 20}) for piq.Len() > 0 { item := piq.Pop().(Item) fmt.Printf("Value: %s, Priority: %d\n", item.value, item.priority) } }
輸出
Value: Item 3, Priority: 20 Value: Item 2, Priority: 10 Value: Item 1, Priority: 3
結論
在本文中,我們編譯並執行了建立優先佇列的程式,使用了兩個示例。在第一個示例中,我們使用堆建立了一個“priorityqueue”,在第二個示例中,我們使用了切片和自定義函式。優先佇列可以用於任務排程、霍夫曼編碼、迪傑斯特拉演算法等等。