Implementing Custom Queues in JavaScript: A Comprehensive Guide
Written on
Queues are an essential data structure in programming, allowing values to be stored and accessed in a specific manner. They operate on the principle of FIFO (First In, First Out), meaning the first element added is the first one to be removed.
JavaScript has evolved significantly since its inception. While its initial purpose did not involve complex functionalities, it has grown to support a wide array of applications. In this tutorial series, we'll delve into data structures and algorithms by creating custom structures in JavaScript.
Understanding Queues
A queue is a linear structure that retains values and allows access in a specified order. The time complexity for operations on a queue is O(1), meaning the number of elements does not impact performance.
In a basic queue, there are three primary operations: enqueue (adding an item), dequeue (removing an item), and front (accessing the first item). To enhance flexibility, I'll also be incorporating several utility methods.
The FIFO Concept
The queue's name reflects its functionality. It serves as a storage where elements are added sequentially and retrieved in the same order.
When elements are enqueued, the first item added will be the first to be dequeued, adhering to the FIFO principle.
Implementing a Queue
There's no singular approach to creating a queue in JavaScript; options include linked lists, pointers, or arrays. For this guide, I'll demonstrate a straightforward implementation using an array alongside basic and helper methods.
Start by defining a Queue class. In the constructor, include a parameter for capacity, which defines the queue’s maximum size. If no value is supplied, it defaults to Infinity, allowing for a flexible structure.
Following the constructor, establish two properties: a private capacity and another for the queue itself. These properties will be initialized within the constructor.
Next, implement three crucial methods: enqueue, dequeue, and front. The enqueue method allows the addition of items unless the queue is at full capacity, in which case it will throw an "Overflow!" error. To enable adding multiple items at once, the rest operator will be utilized.
The dequeue method removes elements from the front of the queue, while the front method merely returns the first element without modifying the queue.
Congratulations! You now have a functional queue ready for use. For added utility, consider implementing additional helper methods. In my version, I’ve included six extra methods, which can be found in the linked repository.
Applying the Queue in a Practical Scenario
To illustrate the queue's utility, we will solve an algorithmic challenge. In chess, the knight moves in an 'L' shape. Our goal is to determine the minimum number of moves needed for the knight to travel from a start point to a destination.
We will employ the Breadth-First Search (BFS) algorithm, exploring all potential moves the knight can make from its current position, storing these in a queue, and calculating the next move sequentially.
Begin by defining a function called findShortestStep, which will accept the source point, destination point, and the board's dimensions. Instantiate the queue with an infinite capacity to track positions.
Set up two 2D arrays to record the knight's path (visited) and the count of moves (knightMove). Given the knight’s movement rules, it can potentially move to eight different positions unless limited by the edges of the board.
Now, we can focus on implementing the BFS algorithm:
- Dequeue the last visited node.
- If this position matches the destination, end the loop and return the distance.
- Otherwise, compute possible movements and mark them as visited.
- For each of the eight possible movements, enqueue them with an incremented distance.
- Repeat from step 1 as long as the queue is not empty.
Mark the source point as visited and enqueue it as the starting condition. Utilize a loop to continuously execute these steps.
While some utility functions have not yet been covered, I have implemented a more extensive version of the queue with additional methods, including isEmpty. Be sure to explore this repository for more insights.
After testing our function with the initial conditions, it should return 6, indicating the knight must take six steps to reach its destination.
Conclusion
Well done! You have successfully constructed a queue using pure JavaScript and applied it to solve a real-world problem. This is just the beginning; stay tuned for future installments where we will explore linked lists, binary trees, graphs, and more.
If you enjoyed this article, please show your support, and feel free to share your thoughts in the comments. Until next time!
If you appreciate content like this and wish to support my writing, consider joining Medium. For $5 a month, you’ll have unlimited access to numerous stories. Using my referral link helps me earn a small commission.