
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Implement Priority Queue Using Balanced Binary Search Tree in Go
In this article,we implement a priority queue using a balanced binary search tree, specifically an AVL tree. Here we are going to use seven different methods: PriorityQueue struct, Node struct, insert, remove, Isempty, size as well as peek along with examples to elaborate the concept.
Syntax
func (pq *PriorityQueue) Insert(value interface{}, priority int)
The Syntax func (pq *PriorityQueue) Insert(value interface{}, priority int) is a method declaration in Golang. It defines a method named Insert that operates on a PriorityQueue instance (receiver) represented by pq.
func (pq *PriorityQueue) Remove() interface{}
The Syntax func (pq *PriorityQueue) Remove() interface{} is another method declaration in Golang. It defines a method named Remove that operates on a PriorityQueue instance (receiver) represented by pq.
func (pq *PriorityQueue) IsEmpty() bool
This method checks if the priority queue represented by pq is empty by examining the head pointer. If the head pointer is nil, it means that there are no nodes in the linked list, and thus the priority queue is empty.
func (pq *PriorityQueue) Size() int
This method calculates the size of the priority queue by iterating through the linked list and counting the number of nodes. It starts from the head node and traverses each next pointer until reaching the end of the linked list.
func (pq *PriorityQueue) Peek() interface{}
This method allows you to peek at the element with the highest priority in the priority queue without removing it. It does so by accessing the value field of the head node, which represents the element at the front of the priority queue.
Algorithm
Define a struct type to represent the elements of the priority queue. Each element should have a value and a priority.
Implement a balanced binary search tree (e.g., AVL tree) data structure to store the elements of the priority queue. The tree nodes should have fields for the element value, priority, left child, right child, and balance factor.
Declare a variable to keep track of the root node of the AVL tree.
Implement a function to insert an element into the priority queue. This function should take the value and priority as parameters, create a new node with the element, and insert it into the AVL tree while maintaining the balance of the tree.
Implement a function to remove and return the element with the highest priority from the priority queue. This function should update the root node of the AVL tree and return the element.
Implement a function to check if the priority queue is empty by checking if the root node is nil.
Example 1
In this example, we define the Node structure with fields for value, priority, left and right child nodes, and height. We then create a sample node and print its details to demonstrate the usage of the Node structure in implementing a priority queue using a balanced binary search tree (AVL tree).
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) }
Output
Value: Sample Value Priority: 1 Left Child: <nil> Right Child: <nil> Height: 1
Example 2
In this example, pq is a pointer to the PriorityQueue struct, and size is a field in the PriorityQueue struct that keeps track of the number of elements in the priority queue.The Size method simply returns the value of the size field, providing the current size of the priority queue.
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) }
Output
Priority queue size: 3
Example 3
The example defines the Peek method for the PriorityQueue struct. The Peek method returns the value of the root node, which represents the element with the highest priority in the priority queue. The main function creates a priority queue, inserts three elements, and then uses the Peek method to get the element with the highest priority. The peeked element is then printed to the console.
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) }
Output
Peeked element: <nil>
Conclusion
In Conclusion, we have successfully implemented a priority queue using a balanced binary search tree, specifically an AVL tree, in Go. The AVL tree provides efficient insertion, removal, and retrieval of elements while maintaining a balanced structure. By assigning priorities to elements, we ensure that higher-priority elements are placed at the front of the queue.