Stacks and Queues are commonly used data structures for extensive computer science and software development which depict a clear horizon for efficient data management, algorithm design, and task scheduling.
In this article, we will learn more about the principles and use cases used in the stack and queues.
What is Stack?
A stack is a data structure where the most recently added element can be accessed and removed. Think of stacks of nested coffee cups. You'll notice to access or remove the last coffee cup, you need to remove others from the top. This is where the principle of LIFO( Last In, First out) comes in. The LIFO principle dictates that the last element added to a stack would be the first to be removed when accessing the stacks. Its time complexity is denoted by a constant O(1). This illustration depicts a stack of cups.
Use Cases
Stacks are extensively used in memory management. For instance, in the local storage of application data, stacks efficiently store and manage data. Additionally, it is also used for undo features in software application, the undo features of an application often relies on stacks to track and update user actions.
Methods
Below are the methods that occur in the operations in stacks.
Push:
- The
push
operation adds an element to the top of the stack.
- The
Pop:
- The
pop
operation removes and returns the element from the top of the stack.
- The
Peek (or Top):
- The
peek
operation returns the element at the top of the stack without removing or modifying it.
- The
isEmpty:
- The
isEmpty
operation checks whether the stack is empty. It returns true if the stack is empty and false otherwise.
- The
Concept
Here, we'll build a shelve that contains different types of coffee cups.
Function
Let's define a function of Stack and also initialize this.stack = []
as an empty array.
function Stack() {
this.stack = [];
}
Push
Define a this.push
function to initialize and push items into the stack.
// Function to push a value onto the stack
this.push = function(coffeeCup) {
this.stack.push(coffeeCup);
};
Pop
Define a this.pop
function to initialize and push items into the stack.
// Function to pop a value onto the stack
this.pop = function() {
this.stack.push();
};
Peek
Define a this.peek
function to retrieve the top item without removing it.
this.peek = function() {
return this.stack[this.stack.length - 1];
};
IsEmpty
Define a this.isEmpty
function to check if the stack is empty.
this.isEmpty = function() {
return this.stack.length === 0;
};
Place all the code together
Put all the code we defined together to see what the whole flow looks like.
function CoffeeStack() {
this.stack = [];
// Function to push a value onto the stack
this.push = function(coffeeCup) {
this.stack.push(coffeeCup);
};
// Function to pop a value onto the stack
this.pop = function() {
this.stack.push();
};
// Function to pop a value onto the stack
this.peek = function() {
return this.stack[this.stack.length - 1];
};
// Function to check if a stack is empty
this.isEmpty = function() {
return this.stack.length === 0;
};
}
Let's test the Stack function.
Copy this code and place it outside the CoffeStack function.
let coffeCups = new CoffeeStack()
// Pushing coffee cups onto the stack
coffeeCups.push("Standard mug ");
coffeeCups.push("Flat white cup");
coffeeCups.push("Cappuccino Cup");
// Peeking at the top coffee cup
console.log("Top Coffee Cup:", coffeeCups.peek()); // Output: Top Coffee Cup: Cappuccino Cup
// Popping a coffee cup from the stack
let removedCup = coffeeCups.pop();
console.log("Removed Coffee Cup:", removedCup); // Output: Removed Coffee Cup: Cappuccino Cup
// Checking if the stack is empty
console.log("Is the stack empty?", coffeeCups.isEmpty()); // Output: Is the stack empty? false
Queues
Queues are data structures that allow the First In, First Out (FIFO) principle. The FIFO principle dictates that the element that is added first is the one to be removed first. Queues share similar methods with Stack but the main distinction lies in the order or pattern of removal. Stack uses the Last In, First Out (LIFO) principle while queues make use of the First In, First Out (FIFO) principle to manage elements in a specific data structure.
Use Cases
Queues are generally used in shared printers. For instance, multiple users may send print jobs to a shared printer and during the whole process, the printer prints orderly as every user sends theirs.
Methods
Below are the queue methods used in everyday scenarios.
enqueue:
- Adding or inserting elements to the top of the queue.
dequeue:
- Removing elements from the top of the queue.
Peek (or Top):
- The
peek
operation returns the element at the top of the queue.
- The
isEmpty:
- The
isEmpty
operation checks whether the queue is empty. It returns true if the queue is empty and false otherwise.
- The
Concept
In the queue, we'll build a VehicleQueue that ordinates the FIFO principle.
Function
Let's define a function of VehicleQueue and also initialize queue = []
as an empty array.
function VehicleQueue() {
const queue = [];
}
Enqueue
Define an enqueue
function to add elements using the queue.unshift(element)
unshift method which adds at the top of the queue.
// Function to push a value onto the stack
function enqueue(element) {
queue.unshift(element);
}
Dequeue
Define a dequeue()
function to remove elements using the queue.pop()
pop method which removes elements at the top queue.
// Function to push a value onto the stack
function dequeue() {
queue.pop();
}
Peek
Define a peek
function to retrieve elements from the front of the queue without removing the element.
// Function to peek a value into the queue
function peek() {
return queue[queue.length - 1];
}
IsEmpty
Define a isEmpty()
that checks if the queue is empty.
function isEmpty() {
return queue.length === 0;
}
Place all the code together
Put all the code we defined together to see what the whole flow looks like.
function VehicleQueue() {
const queue = [];
function enqueue(element) {
queue.unshift(element);
}
function dequeue() {
queue.pop();
}
function peek() {
return queue[queue.length - 1];
}
function isEmpty() {
return queue.length === 0;
}
return { enqueue, dequeue, peek, isEmpty };
}
Let's test the Queue function.
Copy this code and place it outside the Queue function.
const myQueue = VehicleQueue();
myQueue.enqueue("volvo");
myQueue.enqueue("tesla");
console.log("Peek:", myQueue.peek()); // Output: volvo
myQueue.dequeue();
console.log("Peek:", myQueue.peek()); // Output: tesla
console.log("Is Empty:", myQueue.isEmpty()); // Output: false
Conclusion
In the context of using stacks and queues in our article, I hope it helps you understand the use cases and principles underlying the breakdown of certain processes. Moreover, how can you approach explaining stacks and queues, and are there any other use cases you would consider? Let us know in the comment section.