Data Structure Doubly Linked List Practice Questions with Solutions

Introductions

A doubly linked list extends the idea of a singly linked list by giving each node two links: one to the next node and one to the previous node. These practice questions focus on actually working with doubly linked lists, including traversal in both directions, insertion, deletion, searching, counting nodes, and reversing the list. The examples use JavaScript and gradually increase in difficulty. Data Structure Doubly Linked List practice questions with solutions help to understand the concepts.

Question 1: Create and Connect a Doubly Linked List

Question

Create a doubly linked list containing:

10 ⇄ 20 ⇄ 30

Print the elements from the head to the last node.

Solution

A doubly linked list node contains three parts:

Previous | Data | Next

Create a Node class:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

Create three nodes:

let first = new Node(10);
let second = new Node(20);
let third = new Node(30);

Connect the nodes in both directions:

first.next = second;

second.prev = first;
second.next = third;

third.prev = second;

The structure becomes:

null ← 10 ⇄ 20 ⇄ 30 → null

Now traverse from the head:

let head = first;
let current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

Output

10
20
30

Answer

The doubly linked list is:

null ← 10 ⇄ 20 ⇄ 30 → null

Question 2: Traverse a Doubly Linked List in Both Directions

Question

Given:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

Print the elements from the beginning to the end and then from the end to the beginning.

Solution

We first create and connect the nodes:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);
let second = new Node(20);
let third = new Node(30);
let fourth = new Node(40);
let tail = new Node(50);

head.next = second;

second.prev = head;
second.next = third;

third.prev = second;
third.next = fourth;

fourth.prev = third;
fourth.next = tail;

tail.prev = fourth;

Forward Traversal

Start from head and use next:

let current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

This gives:

10 → 20 → 30 → 40 → 50

Backward Traversal

Start from tail and use prev:

current = tail;

while (current !== null) {
    console.log(current.data);
    current = current.prev;
}

This gives:

50 → 40 → 30 → 20 → 10

Output

Forward:
10
20
30
40
50

Backward:
50
40
30
20
10

Answer

A major advantage of a doubly linked list is that it can be traversed in both directions.


Question 3: Count the Number of Nodes

Question

Count the nodes in this doubly linked list:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

Solution

Start from the head and move using next.

Every time we visit a node, increase the counter.

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

head.next = new Node(20);
head.next.prev = head;

head.next.next = new Node(30);
head.next.next.prev = head.next;

head.next.next.next = new Node(40);
head.next.next.next.prev = head.next.next;

head.next.next.next.next = new Node(50);
head.next.next.next.next.prev = head.next.next.next;

let count = 0;
let current = head;

while (current !== null) {
    count++;
    current = current.next;
}

console.log(count);

The count changes like this:

10 → 1
20 → 2
30 → 3
40 → 4
50 → 5

Output

5

Answer

The doubly linked list contains 5 nodes.


Question 4: Search for an Element

Question

Search for 40 in:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

Print its position if it is found.

Solution

Start from the head and check every node.

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

head.next = new Node(20);
head.next.prev = head;

head.next.next = new Node(30);
head.next.next.prev = head.next;

head.next.next.next = new Node(40);
head.next.next.next.prev = head.next.next;

head.next.next.next.next = new Node(50);
head.next.next.next.next.prev = head.next.next.next;

let target = 40;
let current = head;
let position = 0;

while (current !== null) {
    if (current.data === target) {
        console.log("Found at position:", position);
        break;
    }

    current = current.next;
    position++;
}

The search works like this:

10 → Not found
20 → Not found
30 → Not found
40 → Found

Output

Found at position: 3

Answer

The value 40 is found at position 3.


Question 5: Insert a Node at the Beginning

Question

Given:

20 ⇄ 30 ⇄ 40

Insert 10 at the beginning.

Solution

Create the new node:

let newNode = new Node(10);

The new node must point forward to the current head:

newNode.next = head;

The old head must point backward to the new node:

head.prev = newNode;

Finally, update the head:

head = newNode;

The important difference from a singly linked list is that we must update both directions.

Before insertion:

null ← 20 ⇄ 30 ⇄ 40 → null

After insertion:

null ← 10 ⇄ 20 ⇄ 30 ⇄ 40 → null

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(20);

head.next = new Node(30);
head.next.prev = head;

head.next.next = new Node(40);
head.next.next.prev = head.next;

let newNode = new Node(10);

newNode.next = head;
head.prev = newNode;
head = newNode;

let current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

Output

10
20
30
40

Answer

10 is successfully inserted at the beginning.


Question 6: Insert a Node at the End

Question

Given:

10 ⇄ 20 ⇄ 30

Insert 40 at the end.

Solution

Create the new node:

let newNode = new Node(40);

We need to find the last node.

let current = head;

while (current.next !== null) {
    current = current.next;
}

Now current points to 30.

Connect 30 to 40:

current.next = newNode;

Connect 40 back to 30:

newNode.prev = current;

The list becomes:

10 ⇄ 20 ⇄ 30 ⇄ 40

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

head.next = new Node(20);
head.next.prev = head;

head.next.next = new Node(30);
head.next.next.prev = head.next;

let newNode = new Node(40);

let current = head;

while (current.next !== null) {
    current = current.next;
}

current.next = newNode;
newNode.prev = current;

current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

Output

10
20
30
40

Answer

40 is successfully inserted at the end.


Question 7: Insert a Node After a Given Node

Question

Given:

10 ⇄ 20 ⇄ 40 ⇄ 50

Insert 30 after 20.

Solution

First find the node containing 20.

Once found, we need to update four references.

Before insertion:

20 ⇄ 40

Create:

30

The new connections should be:

20 ⇄ 30 ⇄ 40

The important steps are:

newNode.next = current.next;
newNode.prev = current;

current.next.prev = newNode;
current.next = newNode;

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

let second = new Node(20);
let third = new Node(40);
let fourth = new Node(50);

head.next = second;

second.prev = head;
second.next = third;

third.prev = second;
third.next = fourth;

fourth.prev = third;

let target = 20;
let newNode = new Node(30);

let current = head;

while (current !== null) {
    if (current.data === target) {
        newNode.next = current.next;
        newNode.prev = current;

        current.next.prev = newNode;
        current.next = newNode;

        break;
    }

    current = current.next;
}

current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

The structure changes from:

10 ⇄ 20 ⇄ 40 ⇄ 50

to:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

Output

10
20
30
40
50

Answer

30 is successfully inserted after 20.


Question 8: Delete the First Node

Question

Delete the first node from:

10 ⇄ 20 ⇄ 30 ⇄ 40

Solution

The first node is the head.

We need to move the head to the second node:

head = head.next;

But because this is a doubly linked list, we also need to remove the backward link from the new head:

head.prev = null;

Before deletion:

null ← 10 ⇄ 20 ⇄ 30 ⇄ 40 → null

After deletion:

null ← 20 ⇄ 30 ⇄ 40 → null

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

head.next = new Node(20);
head.next.prev = head;

head.next.next = new Node(30);
head.next.next.prev = head.next;

head.next.next.next = new Node(40);
head.next.next.next.prev = head.next.next;

head = head.next;
head.prev = null;

let current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

Output

20
30
40

Answer

The first node containing 10 has been deleted.


Question 9: Delete a Node by Value

Question

Delete the node containing 30 from:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

Solution

First find the node containing 30.

We need to connect its previous node directly to its next node.

Before deletion:

20 ⇄ 30 ⇄ 40

After deletion:

20 ⇄ 40

For the current node:

current.prev.next = current.next;

For the next node:

current.next.prev = current.prev;

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

let second = new Node(20);
let third = new Node(30);
let fourth = new Node(40);
let fifth = new Node(50);

head.next = second;

second.prev = head;
second.next = third;

third.prev = second;
third.next = fourth;

fourth.prev = third;
fourth.next = fifth;

fifth.prev = fourth;

let target = 30;
let current = head;

while (current !== null) {
    if (current.data === target) {
        if (current.prev !== null) {
            current.prev.next = current.next;
        }

        if (current.next !== null) {
            current.next.prev = current.prev;
        }

        break;
    }

    current = current.next;
}

current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

The list changes from:

10 ⇄ 20 ⇄ 30 ⇄ 40 ⇄ 50

to:

10 ⇄ 20 ⇄ 40 ⇄ 50

Output

10
20
40
50

Answer

The node containing 30 has been successfully deleted.


Question 10: Reverse a Doubly Linked List

Question

Reverse this doubly linked list:

10 ⇄ 20 ⇄ 30 ⇄ 40

The expected result is:

40 ⇄ 30 ⇄ 20 ⇄ 10

Solution

In a doubly linked list, every node has two links:

prev
next

To reverse the list, we need to swap these two references for every node.

For example, for node 20:

Before:

10 ← 20 → 30

After swapping:

10 → 20 ← 30

We also need to update the head.

Complete code:

class Node {
    constructor(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

let head = new Node(10);

let second = new Node(20);
let third = new Node(30);
let fourth = new Node(40);

head.next = second;

second.prev = head;
second.next = third;

third.prev = second;
third.next = fourth;

fourth.prev = third;

let current = head;

while (current !== null) {
    let temp = current.prev;

    current.prev = current.next;
    current.next = temp;

    current = current.prev;
}

if (head !== null) {
    head = head.prev;
}

current = head;

while (current !== null) {
    console.log(current.data);
    current = current.next;
}

Let’s understand the important part:

let temp = current.prev;

current.prev = current.next;
current.next = temp;

This swaps the prev and next references.

The original list:

10 ⇄ 20 ⇄ 30 ⇄ 40

becomes:

40 ⇄ 30 ⇄ 20 ⇄ 10

Output

40
30
20
10

Answer

The doubly linked list has been successfully reversed.

Key Takeaways

  • A doubly linked list node contains data, prev, and next.
  • next points to the next node.
  • prev points to the previous node.
  • The first node normally has prev = null.
  • The last node normally has next = null.
  • A doubly linked list can be traversed in both forward and backward directions.
  • Insertion requires maintaining both prev and next links.
  • Deletion also requires updating links on both sides of the removed node.
  • Inserting at the beginning can be done in O(1) time when the head is directly available.
  • Searching a doubly linked list generally takes O(n) time.
  • Reversing a doubly linked list can be done by swapping the prev and next references of each node.
  • Understanding pointer/reference changes is one of the most important skills when practicing doubly linked lists.

FAQs

What is a doubly linked list?

A doubly linked list is a linked list in which every node contains a reference to both the previous node and the next node.

What are the two links in a doubly linked list?

The two links are usually called prev and next. prev points to the previous node, while next points to the next node.

Can a doubly linked list be traversed backward?

Yes. Starting from the last node, you can use the prev reference to move toward the head.

What is the difference between a singly and doubly linked list?

A singly linked list normally has only a next reference, while a doubly linked list has both prev and next references. This allows a doubly linked list to move in both directions.

How do you insert a node into a doubly linked list?

You create the new node and correctly update the prev and next references of the new node and its neighboring nodes.

How do you delete a node from a doubly linked list?

Find the node and connect its previous node to its next node. Then update the next node’s prev reference so both directions remain connected.

What is the time complexity of traversing a doubly linked list?

Traversing all n nodes takes O(n) time because every node needs to be visited.

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top