Doubly linked lists in Javascript

In this article, we are going to discuss a Doubly Linked List Class data structure in JavaScript. This is a linear data structure. Doubly linked lists are almost the same as a singly linked list in all operations, we just need to keep track of one extra link per node. In singly linked lists, we just had next links, in doubly linked lists, we have 2 links, next and prev.

Structure of Doubly Linked List

Doubly linked lists are represented as:

prev data next prev data next prev data next HEAD TAIL NULL NULL

Note that in the class itself, we also need to keep track of the tail (last element) for efficient operations.

Node Structure

Each node contains three parts: previous pointer, data, and next pointer:

<!DOCTYPE html>
<html>
<body>
<script>
function createNode(value) {
    return {
        value: value,
        next: null,
        previous: null,
    };
}

// Example node creation
let node = createNode(10);
console.log(node);
</script>
</body>
</html>

Complete Implementation

Here's the complete doubly linked list implementation with insertion, deletion, and traversal methods:

<!DOCTYPE html>
<html>
<body>
<script>
function createNode(value) {
    return {
        value: value,
        next: null,
        previous: null,
    };
}

class DoublyLinkedList {
    constructor() {
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    // Insert at the end
    insert(value) {
        this.size++;
        let newNode = createNode(value);
        
        if (this.tail) {
            this.tail.next = newNode;
            newNode.previous = this.tail;
            this.tail = newNode;
            return newNode;
        }
        
        this.head = this.tail = newNode;
        return newNode;
    }

    // Insert at the beginning
    insertHead(value) {
        this.size++;
        let newNode = createNode(value);
        
        if (this.head) {
            this.head.previous = newNode;
            newNode.next = this.head;
            this.head = newNode;
            return newNode;
        }
        
        this.head = this.tail = newNode;
        return newNode;
    }

    // Insert at specific index
    insertIndex(value, index) {
        if (index >= this.size) {
            throw new Error("Insert index out of bounds");
        }
        if (index === 0) {
            return this.insertHead(value);
        }
        
        this.size++;
        let currentNode = this.head;
        for (let i = 0; i < index; i++) {
            currentNode = currentNode.next;
        }
        
        let previousNode = currentNode.previous;
        let newNode = createNode(value);
        
        newNode.next = currentNode;
        newNode.previous = previousNode;
        previousNode.next = newNode;
        currentNode.previous = newNode;
        
        return newNode;
    }

    // Remove from the end
    remove() {
        if (this.tail) {
            this.size--;
            let removedTail = this.tail;
            let beforeTail = this.tail.previous;
            
            this.tail = beforeTail;
            if (this.tail) {
                this.tail.next = null;
            } else {
                this.head = null;
            }
            
            return removedTail;
        }
        return undefined;
    }

    // Print the list
    print() {
        document.write("The Elements in the Doubly Linked List are:<br>");
        let current = this.head;
        let output = "";
        
        while (current) {
            let prev = current.previous ? current.previous.value : "null";
            let next = current.next ? current.next.value : "null";
            output += `[${prev}] <- ${current.value} -> [${next}]<br>`;
            current = current.next;
        }
        
        document.write(output);
    }
}

// Example usage
let dLinkedList = new DoublyLinkedList();
dLinkedList.insert(7);
dLinkedList.insert(8);
dLinkedList.insert(9);
dLinkedList.insertHead(5);

document.write("<h3>Doubly Linked List Example</h3>");
dLinkedList.print();
document.write("<br>List size: " + dLinkedList.size);
</script>
</body>
</html>

Key Operations

The main operations in a doubly linked list include:

Operation Time Complexity Description
Insert at end O(1) Add element to tail
Insert at head O(1) Add element to beginning
Insert at index O(n) Add element at specific position
Remove from end O(1) Remove tail element

Advantages

Doubly linked lists provide several advantages over singly linked lists:

  • Bidirectional traversal - can move forward and backward
  • Efficient deletion - no need to traverse from head to find previous node
  • Better for implementing stacks, queues, and deques

Conclusion

Doubly linked lists offer bidirectional navigation with previous and next pointers. While they use more memory than singly linked lists, they provide faster deletion and backward traversal capabilities.

Updated on: 2026-03-15T23:18:59+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements