Linked Lists Using Javascript: A Beginner’s Guide

Camilo Gomez
For beginners by developers
7 min readSep 20, 2020

Understanding Linked Lists

Even as a beginner user of JavaScript, chances are you have come across data structures like arrays, strings and objects. You may or may not have known that these are referred to as “data structures”, and the term may be a bit confusing. Worry not! In this article, I will explain what a data structure is, and will show you how to implement a custom data structure in JavaScript: a linked list. I will also talk about why you would choose to use this data structure over others.

First things first, data what?

So, what is a data structure? Simply put, a data structure refers to a collection of data and how we can operate on such data. We can refer to four fundamental operations: access, insertion, deletion and search.

Let’s use arrays as an example to understand this, as arrays are a simple data structure present in virtually every programming language. Note that the particular internal representation of arrays can vary between different programming languages, but this provides a general overview.

Arrays are structures that store a sequence of data. We can access (and update) the data using bracket notation: myArray[index]. We can add and remove elements from the back using push() and pop(), respectively. We can also add and remove elements at the front using shift() and unshift(), respectively, or in the middle using splice(). We can search using find(). The specifics of how JavaScript performs these operations is not in the scope of this article, but an important thing to keep in mind is this: some operations take longer than others.

For example, we can get the first item of the array very easily. But what if we wanted to add or delete an item at the beginning of the array? Even though this is just one function call away, the indices of every item in the array would have to change, so this operation would be more expensive in terms of computation (check this Wikipedia entry out to learn more). What if we need to regularly add and delete items from the front of the array? Could we do it more efficiently? The answer is yes!

Enter Linked Lists

Linked lists are a data structure made up of nodes. A node is simply a structure composed of some data and one or more pointers. A pointer is just a reference to another node. So now instead of an indexed collection of data (an array), we have a bunch of data where each item has a link to the next one. We refer to the first item of a linked list as the head and the last item as the tail.

I will show you two types of linked lists: singly and doubly linked lists. The general concept of both is the same, there is really just one difference: each node in a singly linked list contains a pointer to the next node in the list, while each node in a doubly linked list contains a pointer to the next node and a pointer to the previous node in the list.

Singly Linked Lists

Diagram of a singly linked list
Diagram of a singly linked list. By Lasindi — Own work, Public Domain, https://commons.wikimedia.org/w/index.php?curid=2245162

Let’s implement a linked list with some basic functionality. To begin our implementation of a singly linked list let’s define our ListNode and our SinglyLinkedList classes:

ListNode and SinglyLinkedList class definitions

When we initialize our list, the head is null because we have no data, and we keep track of the size of our list. Think of how we would calculate the size of our list if we didn’t keep track of the size within our list.

Now we are ready to add some data to our list. Let’s implement the function insertAtHead:

insertAtHead function

We first create a ListNode with our data. This newNode will be the new head of our list. If the list was empty before, we are done. If there were elements in the list, we need to make sure that the new head points to the old head. Finally, we increment the size of our list.

Let’s tackle the deletion problem now. Let’s remove the head of a list.

removeHead function

We first check if there are actually any elements in the list. If we indeed have elements, the next pointer of our current head will become the new head. And let’s not forget to decrement the size of our list.

Let’s think about how we can find an element somewhere in the middle of the array and delete it. We will need to find the element by its value, and keep track and the node right before. Once we find the element we want to remove, we can just update the pointer on the previous element, and decrement our size variable.

deleteByValue function

Feel free to play with the singly linked list in this CodePen.

What if instead of inserting a node at the end, we wanted to remove the last node? With a reference to the tail, we can insert a new node because we can simply update the old tail’s pointer. But if we wanted to delete the tail, we would need access to the node immediately before it.

Enter Doubly Linked Lists

So what if every node contained a reference to both the previous node and the next node? Now we can insert and delete at both the head and the tail without any traversal.

Diagram of a doubly linked list
Diagram of a doubly linked list. By Lasindi — Own work, Public Domain, https://commons.wikimedia.org/w/index.php?curid=2245165

Great, let’s implement it. We can start by modifying our ListNode slightly and List classes slightly:

ListNode and DoublyLinkedList class definitions

As you can see, we now have our data, and two pointers, previous and next, and a reference to the tail of our list.

Inserting and deleting nodes will be very similar to what we did when using singly linked lists, but now we do not need to keep track of the previous node (we just use our trusty pointer). Keep in mind that in every operation we need to update two pointers instead of one.

With doubly linked lists, we can start traversing the list and add or remove elements from both the head and the tail. I’ve created this CodePen for you to play with a doubly linked list.

So why do we need another data structure?

Data structures are tools that help developers get the job done. If you needed to drive a nail into the wall, a hammer would be the tool to get the job done. A sturdy screwdriver could also get the job done, but with a hammer at hand, why choose another tool?

The same applies to data structures. Different data structures are better suited for different operations. If your application requires a lot of random access you should probably use an array. But if your application requires a lot of insertions and deletions at the head, a linked list is probably a better choice. Linked lists can be useful to implement some other data structures, such as stacks or queues. Oftentimes, edges in graphs are represented as adjacency lists, too. If you think of a chess game, you can think of the sequence of moves as a linked list. If you ever read a Wikipedia article and fall into a black hole and clicking link after link, you can think of this as a linked list as well: when you hit back on your browser, you are traversing the linked list of your browsers recent history.

Feel free to try things out to get more comfortable with linked lists. Keep in mind these implementations touch just the fundamentals. Here are some other functions that you can try to implement to get a better understanding of linked lists:

  • Think about how we can access elements by “index”.
  • Using the previous search, how can we insert and delete an element at index i?
  • In our doubly linked list, implement a search/delete/insert at index i from the tail.
  • Write a function to calculate the size of the list (without using our class variable)
  • JavaScript’s function concat() is used to merge two arrays. Think of how you could merge two linked lists (hint: This is a very fast operation!)

References:

Groner, Loiane. Learning JavaScript Data Structures and Algorithms: Write complex and powerful JavaScript code using the latest ECMAScript, 3rd Edition, Packt Publishing, Limited, 2018.

Bae, Sammie. Javascript Data Structures and Algorithms: An Introduction to Understanding and Implementing Core Data Structure and Algorithm Fundamentals. Apress, 2019.

--

--