使用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”,在第二個示例中,我們使用了切片和自定義函式。優先佇列可以用於任務排程、霍夫曼編碼、迪傑斯特拉演算法等等。

更新於: 2023年7月5日

2K+ 瀏覽量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告