DEV Community

Cover image for Understanding Stack and Queues in JavaScript
Emmanuel Umeh
Emmanuel Umeh

Posted on

Understanding Stack and Queues in JavaScript

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.

Image description

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.

Pop:

The pop operation removes and returns the element from the top of the stack.

Peek (or Top):

The peek operation returns the element at the top of the stack without removing or modifying it.

isEmpty:

The isEmpty operation checks whether the stack is empty. It returns true if the stack is empty and false otherwise.

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 = [];
  }
Enter fullscreen mode Exit fullscreen mode

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);
    };
Enter fullscreen mode Exit fullscreen mode

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();
    };
Enter fullscreen mode Exit fullscreen mode

Peek

Define a this.peek function to retrieve the top item without removing it.

      this.peek = function() {
      return this.stack[this.stack.length - 1];
    };
Enter fullscreen mode Exit fullscreen mode

IsEmpty

Define a this.isEmpty function to check if the stack is empty.

this.isEmpty = function() {
      return this.stack.length === 0;
    };
Enter fullscreen mode Exit fullscreen mode

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;
    };

  }
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Image description

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.

isEmpty:

The isEmpty operation checks whether the queue is empty. It returns true if the queue is empty and false otherwise.

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 = [];

  }
Enter fullscreen mode Exit fullscreen mode

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);
    }
Enter fullscreen mode Exit fullscreen mode

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();
    }
Enter fullscreen mode Exit fullscreen mode

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];
    }
Enter fullscreen mode Exit fullscreen mode

IsEmpty

Define a isEmpty() that checks if the queue is empty.

   function isEmpty() {
      return queue.length === 0;
    }
Enter fullscreen mode Exit fullscreen mode

Place all the code together

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 };
}


Enter fullscreen mode Exit fullscreen mode

Let's test the Queue function.

Copy this code and place it outside the Queue function.

const myQueue = VehicleQueue();
myQueue.enqueue("volvo");
myQueue.enqueue("volvo");

console.log("Peek:", myQueue.peek()); // Output: car1
myQueue.dequeue();
console.log("Peek:", myQueue.peek()); // Output: car2
console.log("Is Empty:", myQueue.isEmpty()); // Output: false
Enter fullscreen mode Exit fullscreen mode

Conclusion

In the context of using stacks and queues in our article, I hope it helps you understand the use cases and principle underlying the breakdown of some 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.

Top comments (0)