Stack, Queue, Linked List and Hash Table In JavaScript

JavaScript in Data Structure

The Stack, Queue, Linked List and Hash Table are some of the most common data structures in computer science. All three hold a collection of elements and can be traversed. In the linked list one pointer is used to keep track of the head and another keeps track of the next value. On the other hand a stack and queue keeps track of the top value, size and previous value in most cases.

Each implementation of these data structures may differ slightly. The linked list can be written as a circularly linked list, double linked list or singly linked list. Depending on the implementation a stack may, or may not, keep track of the previous value.

Some other common data structures include trees, tries & graphs, heaps, array lists and hash tables. For the sake of this blog article we’ll just discuss Stack, Queue, Linked List and Hash Table using JavaScript

In this blog post we’ll discuss how to implement a stack, queue and linked list using JavaScript.

I encourage you before you begin to try to implement these data structures by yourself first. Check back here and see how you did.

Stack

Arguably the most important Stack in JavaScript is the call stack where we push in the scope of a function whenever we execute it. Programmatically, it’s just an array with two principled operations: push and pop. Push addselements to the top of the array, while Pop removes them from the same location. In other words, Stacks follow the “Last In, First Out” protocol (LIFO).

Below is an example of a Stack in code. Notice that we can reverse the order of the stack: the bottom becomes the top and the top becomes the bottom. As such, we can use the array’s unshift and shift methods in place of pushand pop, respectively.

Stack in Javascript
An example of a Queue in code:let stack = [];  
//push
stack.push(5);
stack.push(10);

//pop
stack.pop(); //10
stack.pop(); //5

Queue

JavaScript is an event-driven programming language which makes it possible to support non-blocking operations. Internally, the browser manages only one thread to run the entire JavaScript code, using the event queue to enqueue listeners and the event loop to listen for the registered events. To support asynchronicity in a single-threaded environment (to save CPU resources and enhance the web experience), listener functions dequeue and execute only when the call stack is empty. Promises depend on this event-driven architecture to allow a “synchronous-style” execution of asynchronous code that does not block other operations.

Programmatically, Queues are just arrays with two primary operations: unshift and pop. Unshift enqueues items to the end of the array, while Popdequeues them from the beginning of the array. In other words, Queues follow the “First In, First Out” protocol (FIFO). If the direction is reversed, we can replace unshift and pop with push and shift, respectively.

Queue in JavaScript
let queue = [];

//enqueue
queue.push(5);
queue.push(3);
queue.push(3);

//dequeue
queue.shift(); // 1
queue.shift(); //2
queue.shift(); // 3

In JavaScript we can use push as are enqueue and shift as a dequeue. The shift will retrieve elements from the front side of you array!

We could implement both the stack and queue using functions, however this just easier and proves the point.

Linked List

Like arrays, Linked Lists store data elements in sequential order. Instead of keeping indexes, linked lists hold pointers to other elements. The first node is called the head while the last node is called the tail. In a singly-linked list, each node has only one pointer to the next node. Here, the head is where we begin our walk down the rest of the list. In a doubly-linked list, a pointer to the previous node is also kept. Therefore, we can also start from the tail and walk “backwards” toward the head.

Linked lists have constant-time insertions and deletions because we can just change the pointers. To do the same operations in arrays requires linear timebecause subsequent items need to be shifted over. Also, linked lists can grow as long as there is space. However, even “dynamic” arrays that automatically resize could become unexpectedly expensive. Of course, there’s always a tradeoff. To lookup or edit an element in a linked list, we might have to walk the entire length which equates to linear time. With array indexes, however, such operations are trivial.

Like arrays, linked lists can operate as stacks. It’s as simple as having the head be the only place for insertion and removal. Linked lists can also operate as queues. This can be achieved with a doubly-linked list, where insertion occurs at the tail and removal occurs at the head, or vice versa.

Linked lists are useful on both the client and server. On the client, state management libraries like Redux structure its middleware logic in a linked-list fashion. When actions are dispatched, they are piped from one middleware to the next until all is visited before reaching the reducers. On the server, web frameworks like Express also structure its middleware logic in a similar fashion. When a request is received, it is piped from one middleware to the next until a response is issued.

Single Linked List

Single linked list in Javscript
Array:          0: 12    1: 99    2: 37Linked List:    head → 12 → 99 → 37 → 
Single linked list in Javscript

Doubly Linked List

A doubly-linked list is the same as a singly-linked list, except that every node has both a next pointer pointing forwards and a pre (previous) pointer pointing backwards. This takes more memory to maintain and the logic of the methods becomes a little more difficult to reason about. It allows some speed optimizations. It would look like this.

Double linked list in Javscript
head

← 12 ⇄ 99 ⇄ 37 →
const list = {
head: → { value: 12, pre: ∅, next: ⤵ }
{ value: 99, pre: ⤴, next: ⤵ }
{ value: 37, pre: ⤴, next: }
};

Circular Linked List

A circular linked list has no null value at the end. The next value of the last item is set equal to the head.

Circular linked list in Javscript
head

12 ← 37
↘ ↑
99
const list = {
head: → { value: 12, next: ⤵ }
{ value: 99, next: ⤵ }
{ value: 37, next: list.head }
};

Hash Table

I’ll try to give a non technical answer here.

A Hash table is one which helps you reduce the possible places where you can find an element, really. What you do is given a set of possible places, you chop (hacher) them down into little pieces. To place an object, associate it with a piece based on the element’s property.

When you want to check if an object exists, you will only try to check the check that piece.

An analogy will be looking for Karthik in the ‘K’ section of a regular phonebook instead of the entire book. This is, assuming you decided to organize the names initially and put names starting with ‘K’ on the K-page.

Hash Table in javascript

--

--