In this tutorial, we will learn about “how to implement Queue in Golang using step by step guide“. Queue is one of the most commonly used data structure. To understand Queue in a lay man term, relate is with a real life example. For example, 5 man standing out a shop in a Queue will collect the order in sequential order i.e one who is standing in the front will be given the stuff first followed by rest. This is exactly how the Queue data structure works in programming world. We will dive deep into the concept and its implementation in Golang in the upcoming sections of this tutorial.
What is Queue?
A Queue is a linear data structure that follows the First in, First out principle which means that element that is added first is the one that gets removed first. We can understand the Queue by taking an example. Suppose there is a Queue made outside a grocery shop which has 10 person standing in the Queue. The shopkeeper will provide the stuffs to the person who joined the Queue first followed by second person and so on. We will understand the concept with more clarity when we discuss about different operations that can be done on a Queue in next section.
Queue Operations
Enqueue Operation
In Queue, Enqueue() is a method using which we add an element to the end (rear) of the Queue. When we add an element, the length of the Queue gets extended by 1. Therefore, if you add 10 elements to an empty Queue, the length will get extended to 10. I have taken an example to explain the enqueue() operation as shown below.
Consider we have a list of numbers (8, 4, 5, 9, 6, 1, 12) which must be enqueued. In this process, at index 0, the first element(8) from the list will get added. Next element from the list(4) will get added in the next index i.e 1 and so on. The last element(12) from the list will get added in the last index i.e at index 6
Dequeue Operation
In Queue, Dequeue() is a method using which we can remove the element from the front (head) of the queue. In this method, the element at the front is removed and the next element in line becomes the new front. This operation follows the FIFO principle which ensures that the oldest element is dequeued first.
In the same example as we discussed above, we can perform the dequeue() operation. When we invoke the dequeue() method, the first element which gets removed from the queue will be the first element which was added in the queue. Similarly, the dequeue will happen for other elements in the queue. The last element that will be dequeued from the queue is the last element that was added in the queue. It is demonstrated in the below diagram.
Peek or Front Operation
In Queue, Peek() is a method which is used to retrieve the element at the front without removing it. It allows you to examine the element at the front of the queue without altering the queue itself. This operation becomes useful when you want to inspect the next element to be dequeued.
IsEmpty Operation
In Queue, isEmpty() is a method which checks if the queue is empty. It will return a Boolean value indicating whether the queue is devoid of elements. It helps in avoiding errors that might occur if attempting to dequeue from an empty queue.
IsFull Operation
In Queue, isFull() is a method which checks if the Queue has reached its maximum capacity. This method is relevant for bounded queues where a fixed size is imposed. This operation ensures that the queue does not overflow which prevents the addition of more elements.
How to Implement Queue in Golang [Step by Step Guide]
Also Read: How to Implement Stack in Golang [Step by Step Guide]
So far we have gained the understanding about the Queue data structure and all the supported operations. In this section, we will write a Golang code which will create an empty Queue. We will then write logics to create all the discussed methods to Queue. Save below code in a file say queue.go and go through the code by yourself once.
package main import "fmt" type queue struct { data []int } //Enqueue in the queue func (q *queue) Enqueue(val int) { q.data = append(q.data, val) } //Dequeue from the queue func (q *queue) Dequeue() { q.data = q.data[1:] } //Peek operation func (q queue) Peek() { front := q.data[0] fmt.Println("Element present at the front of given Queue: ", front) } //isEmpty operation func (q queue) isEmpty() { if q.data == nil { fmt.Println("Given Queue is empty") } } //Print elements of queue func (q queue) PrintQueue() { fmt.Println("Queue Data: ", q.data) } func main() { q1 := queue{} addNum := []int{8, 4, 5, 9, 6, 1, 12} q1.isEmpty() for i := range addNum { q1.Enqueue(addNum[i]) } q1.PrintQueue() q1.Peek() q1.Dequeue() q1.PrintQueue() q1.Dequeue() q1.PrintQueue() q1.Enqueue(19) q1.PrintQueue() }
func (q *queue) Enqueue(val int) { q.data = append(q.data, val) }
func (q *queue) Dequeue() { q.data = q.data[1:] }
func (q queue) Peek() { front := q.data[0] fmt.Println("Element present at the front of given Queue: ", front) }
func (q queue) isEmpty() { if q.data == nil { fmt.Println("Given Queue is empty") } }
func (q queue) PrintQueue() { fmt.Println("Queue Data: ", q.data) }
> go run .\queue.go Given Queue is empty Queue Data: [8 4 5 9 6 1 12] Element present at the front of given Queue: 8 Queue Data: [4 5 9 6 1 12] Queue Data: [5 9 6 1 12] Queue Data: [5 9 6 1 12 19]
How to Implement isFull() Method?
As we know, the isFull() method of Queue works only with bounded Queue which means Queue with fixed size or capacity. In the previous example which we used to implement all the Queue methods except the isFull() method, we used slice of dynamic size. To implement the isFull() method, we have to create a slice with fixed capacity. Let us modify the same code which we used earlier and add the logic to implement isFull() method as shown below.
package main import "fmt" type queue struct { data []int capacity int } // Enqueue in the queue func (q *queue) Enqueue(val int) { if q.isFull() { fmt.Println("Queue is full. Cannot enqueue more elements.") return } q.data = append(q.data, val) fmt.Printf("Enqueued: %d\n", val) } // isFull operation func (q *queue) isFull() bool { return len(q.data) == q.capacity } // Print elements of queue func (q queue) PrintQueue() { fmt.Println("Queue Data:", q.data) } func main() { // Set the capacity of the queue q1 := queue{capacity: 5} addNum := [7]int{8, 4, 5, 9, 6, 1, 12} for i := range addNum { q1.Enqueue(addNum[i]) } q1.PrintQueue() }
> go run .\queue.go Enqueued: 8 Enqueued: 4 Enqueued: 5 Enqueued: 9 Enqueued: 6 Queue is full. Cannot enqueue more elements. Queue is full. Cannot enqueue more elements. Queue Data: [8 4 5 9 6]
NOTE:
Summary
We have learnt about the Queue data structure in depth. We also learnt about the important Queue operations i.e enqueue() and dequeue() along with other supported operations like peek(), isEmpty() and isFull().