使用平衡二叉搜尋樹(例如AVL樹)實現優先佇列的Go語言程式


在這篇文章中,我們將使用平衡二叉搜尋樹,特別是AVL樹,來實現優先佇列。我們將使用七種不同的方法:PriorityQueue結構體、Node結構體、insert、remove、Isempty、size以及peek,並透過示例來闡述這個概念。

語法

func (pq *PriorityQueue) Insert(value interface{}, priority int)

語法`func (pq *PriorityQueue) Insert(value interface{}, priority int)`是Go語言中的方法宣告。它定義了一個名為Insert的方法,該方法操作由pq表示的PriorityQueue例項(接收者)。

func (pq *PriorityQueue) Remove() interface{}

語法`func (pq *PriorityQueue) Remove() interface{}`是Go語言中的另一個方法宣告。它定義了一個名為Remove的方法,該方法操作由pq表示的PriorityQueue例項(接收者)。

func (pq *PriorityQueue) IsEmpty() bool

此方法透過檢查頭指標來檢查由pq表示的優先佇列是否為空。如果頭指標為nil,則表示連結串列中沒有節點,因此優先佇列為空。

func (pq *PriorityQueue) Size() int

此方法透過迭代遍歷連結串列並計算節點數來計算優先佇列的大小。它從頭節點開始,遍歷每個next指標,直到到達連結串列的末尾。

func (pq *PriorityQueue) Peek() interface{}

此方法允許您檢視優先佇列中具有最高優先順序的元素,而無需將其移除。它透過訪問頭節點的value欄位來實現,該欄位表示優先佇列前端的元素。

演算法

  • 定義一個結構體型別來表示優先佇列的元素。每個元素都應該有一個值和一個優先順序。

  • 實現一個平衡二叉搜尋樹(例如,AVL樹)資料結構來儲存優先佇列的元素。樹節點應該包含元素值、優先順序、左子節點、右子節點和平衡因子欄位。

  • 宣告一個變數來跟蹤AVL樹的根節點。

  • 實現一個函式將元素插入到優先佇列中。此函式應將值和優先順序作為引數,建立一個包含該元素的新節點,並將其插入到AVL樹中,同時保持樹的平衡。

  • 實現一個函式來移除並返回優先佇列中具有最高優先順序的元素。此函式應更新AVL樹的根節點並返回該元素。

  • 實現一個函式,透過檢查根節點是否為nil來檢查優先佇列是否為空。

示例1

在這個例子中,我們定義了包含值、優先順序、左右子節點和高度欄位的Node結構體。然後我們建立一個示例節點並列印其詳細資訊,以演示在使用平衡二叉搜尋樹(AVL樹)實現優先佇列時Node結構體的用法。

package main

import "fmt"

type Node struct {
   value    interface{}
   priority int
   left     *Node
   right    *Node
   height   int
}

func main() {
	
   node := &Node{
      value:    "Sample Value",
      priority: 1,
      left:     nil,
      right:    nil,
      height:   1,
	}

	
   fmt.Println("Value:", node.value)
   fmt.Println("Priority:", node.priority)
   fmt.Println("Left Child:", node.left)
   fmt.Println("Right Child:", node.right)
   fmt.Println("Height:", node.height)
}

輸出

Value: Sample Value
Priority: 1
Left Child: <nil>
Right Child: <nil>
Height: 1

示例2

在這個例子中,pq是指向PriorityQueue結構體的指標,size是PriorityQueue結構體中跟蹤優先佇列中元素數量的欄位。Size方法只是返回size欄位的值,提供優先佇列的當前大小。

package main

import (
   "fmt"
)

type Node struct {
   value    interface{}
   priority int
   left     *Node
   right    *Node
   height   int
   size     int
}

type PriorityQueue struct {
   root *Node
}

func (pq *PriorityQueue) Size() int {
   return getSize(pq.root)
}

func getSize(node *Node) int {
   if node == nil {
      return 0
   }
   return node.size
}

func (pq *PriorityQueue) Insert(value interface{}, priority int) {
   pq.root = insertNode(pq.root, value, priority)
}

func insertNode(node *Node, value interface{}, priority int) *Node {
   if node == nil {
      return &Node{
         value:    value,
         priority: priority,
         height:   1,
         size:     1,
      }
   }

   if priority < node.priority {
      node.left = insertNode(node.left, value, priority)
   } else {
      node.right = insertNode(node.right, value, priority)
   }

   node.height = max(height(node.left), height(node.right)) + 1
   node.size = getSize(node.left) + getSize(node.right) + 1

   return node
}

func height(node *Node) int {
   if node == nil {
      return 0
   }
   return node.height
}

func max(a, b int) int {
   if a > b {
      return a
   }
   return b
}

func main() {
   pq := PriorityQueue{}

   pq.Insert("Apple", 2)
   pq.Insert("Banana", 3)
   pq.Insert("Orange", 1)

   size := pq.Size()
	
   fmt.Println("Priority queue size:", size)
}

輸出

Priority queue size: 3

示例3

此示例定義了PriorityQueue結構體的Peek方法。Peek方法返回根節點的值,該值表示優先佇列中具有最高優先順序的元素。主函式建立一個優先佇列,插入三個元素,然後使用Peek方法獲取具有最高優先順序的元素。然後將檢視的元素列印到控制檯。

package main

import (
   "fmt"
)

type Node struct {
   value    interface{}
   priority int
   left     *Node
   right    *Node
   height   int
   size     int
}

type PriorityQueue struct {
   root *Node
}

func (pq *PriorityQueue) Insert(value interface{}, priority int) {
   newNode := &Node{
      value:    value,
      priority: priority,
      height:   1,
      size:     1,
   }

   pq.root = pq.insertNode(pq.root, newNode)
}

func (pq *PriorityQueue) insertNode(root *Node, newNode *Node) *Node {
   return root
}

func (pq *PriorityQueue) Peek() interface{} {
   if pq.root == nil {
      return nil
   }

   current := pq.root
   for current.right != nil {
      current = current.right
   }

   return current.value
}

func main() {
   pq := PriorityQueue{}
   
   pq.Insert("Apple", 2)
   pq.Insert("Banana", 3)
   pq.Insert("Orange", 1)

   peeked := pq.Peek()

   fmt.Println("Peeked element:", peeked)
}

輸出

Peeked element: <nil>

結論

總之,我們已經成功地在Go語言中使用平衡二叉搜尋樹,特別是AVL樹,實現了優先佇列。AVL樹提供高效的元素插入、移除和檢索,同時保持平衡的結構。透過為元素分配優先順序,我們確保高優先順序元素位於佇列的前端。

更新於:2023年7月20日

199 次瀏覽

啟動您的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.