Merge Sort for Doubly Linked List

Last Updated : 20 Aug, 2026

Given a doubly linked list, The task is to sort the doubly linked list in non-decreasing order using merge sort.

Examples:

Input: 10 <-> 8 <-> 4 <-> 2
Output: 2 <-> 4 <-> 8 <-> 10

Input: 5 <-> 3 <-> 2
Output: 2 <-> 3 <-> 5

Try It Yourself
redirect icon

Merge sort for a singly linked list has already been discussed. The important change here is to modify the previous pointers when merging two lists.

Approach :

The idea is to maintain a mergeSort function that sorts the list in three steps:

Divide: Split the list into two halves using a mid node. The first half runs from the head to just before mid, and the second half starts at mid and runs to the end.

Recursively Sort: Apply mergeSort recursively on both halves.

Merge: Merge the two sorted halves into one sorted list and return the new head node.

C++
// C++ program for merge sort on doubly linked list

#include <iostream>
using namespace std;

class Node {
  public:
    int data;
    Node *next;
    Node *prev;

    Node(int x) {
        data = x;
        next = nullptr;
        prev = nullptr;
    }
};

// Function to split the doubly linked list into two halves
Node *split(Node *head) {
    Node *fast = head;
    Node *slow = head;

    // Move fast pointer two steps and slow pointer
    // one step until fast reaches the end
    while (fast!= nullptr && fast->next!= nullptr 
           && fast->next->next!= nullptr) {
        fast = fast->next->next;
        slow = slow->next;
    }

    // Split the list into two halves
    Node *temp = slow->next;
    slow->next = nullptr;
    if (temp!= nullptr) {
        temp->prev = nullptr;
    }
    return temp;
}

// Function to merge two sorted doubly linked lists
Node *merge(Node *first, Node *second) {
  
    // If either list is empty, return the other list
    if (first == nullptr) {
        return second;
    }
    if (second == nullptr) {
        return first;
    }

    // Pick the smaller value between first and second nodes
    if (first->data < second->data) {

        // Recursively merge the rest of the lists and
        // link the result to the current node
        first->next = merge(first->next, second);
        if (first->next!= nullptr) {
            first->next->prev = first;
        }
        first->prev = nullptr;
        return first;
    }
    else {
        // Recursively merge the rest of the lists
        // and link the result to the current node
        second->next = merge(first, second->next);
        if (second->next!= nullptr) {
            second->next->prev = second;
        }
        second->prev = nullptr;
        return second;
    }
}

// Function to perform merge sort on a doubly linked list
Node *mergeSort(Node *head) {
  
    // Base case: if the list is empty or has only one node, 
    // it's already sorted
    if (head == nullptr || head->next == nullptr) {
        return head;
    }

    // Split the list into two halves
    Node *second = split(head);

    // Recursively sort each half
    head = mergeSort(head);
    second = mergeSort(second);

    // Merge the two sorted halves
    return merge(head, second);
}

void printList(Node *head) {
    Node *curr = head;
    while (curr!= nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

int main() {
  
    // Create a hard-coded doubly linked list:
    // 10 <-> 8 <-> 5 <-> 2
    Node *head = new Node(10);
    head->next = new Node(8);
    head->next->prev = head;
    head->next->next = new Node(5);
    head->next->next->prev = head->next;
    head->next->next->next = new Node(2);
    head->next->next->next->prev = head->next->next;

    head = mergeSort(head);

    printList(head);

    return 0;
}
C
// C program for merge sort on doubly linked list

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
    struct Node *prev;
};

// Function to split the doubly linked list into
// two halves
struct Node *split(struct Node *head) {
    struct Node *fast = head;
    struct Node *slow = head;

    // Move fast pointer two steps and slow pointer
    // one step until fast reaches the end
    while (fast != NULL && fast->next != NULL 
           && fast->next->next != NULL) {
        fast = fast->next->next;
        slow = slow->next;
    }

    // Split the list into two halves
    struct Node *temp = slow->next;
    slow->next = NULL;
    if (temp != NULL) {
        temp->prev = NULL;
    }
    return temp;
}

// Function to merge two sorted doubly linked lists
struct Node *merge(struct Node *first, struct Node *second) {
  
    // If either list is empty, return the other list
    if (first == NULL)
        return second;
    if (second == NULL)
        return first;

    // Pick the smaller value between first and 
   // second nodes
    if (first->data < second->data) {
      
        // Recursively merge the rest of the lists and
        // link the result to the current node
        first->next = merge(first->next, second);
        if (first->next != NULL) {
            first->next->prev = first;
        }
        first->prev = NULL;
        return first;
    }
    else {
      
        // Recursively merge the rest of the lists and
        // link the result to the current node
        second->next = merge(first, second->next);
        if (second->next != NULL) {
            second->next->prev = second;
        }
        second->prev = NULL;
        return second;
    }
}

// Function to perform merge sort on a doubly linked list
struct Node *mergeSort(struct Node *head) {
  
    // Base case: if the list is empty or has only
    // one node, it's already sorted
    if (head == NULL || head->next == NULL) {
        return head;
    }

    // Split the list into two halves
    struct Node *second = split(head);

    // Recursively sort each half
    head = mergeSort(head);
    second = mergeSort(second);

    // Merge the two sorted halves
    return merge(head, second);
}

void printList(struct Node *head) {
    struct Node *curr = head;
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");
}

struct Node *createNode(int data) {
    struct Node *newNode =
      (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    newNode->prev = NULL;
    return newNode;
}
int main() {
  
  	// Create a hard-coded doubly linked list:
    // 10 <-> 8 <-> 5 <-> 2
    struct Node *head = createNode(10);
    head->next = createNode(8);
    head->next->prev = head;
    head->next->next = createNode(5);
    head->next->next->prev = head->next;
    head->next->next->next = createNode(2);
    head->next->next->next->prev = head->next->next;

    head = mergeSort(head);

    printList(head);

    return 0;
}
Java
// Java program for merge sort on doubly 
// linked list

class Node {
    int data;
    Node next;
    Node prev;

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

public class GfG {

    // Function to split the doubly 
   // linked list into twohalves
    static Node split(Node head) {
        Node fast = head;
        Node slow = head;

        // Move fast pointer two steps and slow pointer one
        // step until fast reaches the end
        while (fast != null && fast.next != null
               && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        // Split the list into two halves
        Node temp = slow.next;
        slow.next = null;
        if (temp != null) {
            temp.prev = null;
        }
        return temp;
    }

    // Function to merge two sorted doubly linked lists
    static Node merge(Node first, Node second) {

        // If either list is empty, return the other list
        if (first == null)
            return second;
        if (second == null)
            return first;

        // Pick the smaller value between first and second
        // nodes
        if (first.data < second.data) {

            // Recursively merge the rest of the lists and
            // link the result to the current node
            first.next = merge(first.next, second);
            if (first.next != null) {
                first.next.prev = first;
            }
            first.prev = null;
            return first;
        }
        else {
            // Recursively merge the rest of the lists and
            // link the result to the current node
            second.next = merge(first, second.next);
            if (second.next != null) {
                second.next.prev = second;
            }
            second.prev = null;
            return second;
        }
    }

    // Function to perform merge sort on 
  	// a doubly linked list
    static Node mergeSort(Node head) {
      
        // Base case: if the list is empty or has only one
        // node, it's already sorted
        if (head == null || head.next == null) {
            return head;
        }

        // Split the list into two halves
        Node second = split(head);

        // Recursively sort each half
        head = mergeSort(head);
        second = mergeSort(second);

        // Merge the two sorted halves
        return merge(head, second);
    }

    static void printList(Node head) {
        Node curr = head;
        while (curr != null) {
            System.out.print(curr.data + " ");
            curr = curr.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {

        // Create a hard-coded doubly linked list:
        // 10 <-> 8 <-> 5 <-> 2
        Node head = new Node(10);
        head.next = new Node(8);
        head.next.prev = head;
        head.next.next = new Node(5);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(2);
        head.next.next.next.prev = head.next.next;

        head = mergeSort(head);

        printList(head);
    }
}
Python
# Python Program for merge sort on doubly linked list

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

# Function to split the doubly linked
# list into two halves
def split(head):
    fast = head
    slow = head

    # Move fast pointer two steps and slow pointer
    # one step until fast reaches the end
    while fast is not None and fast.next is not None \
    				and fast.next.next is not None:
        fast = fast.next.next
        slow = slow.next

    # Split the list into two halves
    temp = slow.next
    slow.next = None
    if temp is not None:
        temp.prev = None
    return temp

# Function to merge two sorted doubly linked lists
def merge(first, second):

    # If either list is empty, return the other list
    if first is None:
        return second
    if second is None:
        return first

    # Pick the smaller value between first
    # and second nodes
    if first.data < second.data:

        # Recursively merge the rest of the lists
        # and link the result to the current node
        first.next = merge(first.next, second)
        if first.next is not None:
            first.next.prev = first
        first.prev = None
        return first
    else:

        # Recursively merge the rest of the lists and
        # link the result to the current node
        second.next = merge(first, second.next)
        if second.next is not None:
            second.next.prev = second
        second.prev = None
        return second

# Function to perform merge sort on a
# doubly linked list
def mergeSort(head):

    # Base case: if the list is empty or has only
    # one node, it's already sorted
    if head is None or head.next is None:
        return head

    # Split the list into two halves
    second = split(head)

    # Recursively sort each half
    head = mergeSort(head)
    second = mergeSort(second)

    # Merge the two sorted halves
    return merge(head, second)


def printList(head):
    curr = head
    while curr is not None:
        print(curr.data, end=" ")
        curr = curr.next
    print()

if __name__ == "__main__":

    # Create a hard-coded doubly linked list:
    # 10 <-> 8 <-> 5 <-> 2
    head = Node(10)
    head.next = Node(8)
    head.next.prev = head
    head.next.next = Node(5)
    head.next.next.prev = head.next
    head.next.next.next = Node(2)
    head.next.next.next.prev = head.next.next

    head = mergeSort(head)

    printList(head)
C#
// C# Program for merge sort
// on doubly linked list

using System;

class Node {
    public int data;
    public Node next;
    public Node prev;

    public Node(int data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

class GfG {
  
    // Function to split the doubly linked list into two
    // halves
    static Node Split(Node head) {
        Node fast = head;
        Node slow = head;

        // Move fast pointer two steps and slow pointer one
        // step until fast reaches the end
        while (fast != null && fast.next != null
               && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        // Split the list into two halves
        Node temp = slow.next;
        slow.next = null;
        if (temp != null) {
            temp.prev = null;
        }
        return temp;
    }

    // Function to merge two sorted doubly linked lists
    static Node Merge(Node first, Node second) {
      
        // If either list is empty, return the other list
        if (first == null)
            return second;
        if (second == null)
            return first;

        // Pick the smaller value between first and second
        // nodes
        if (first.data < second.data) {
          
            // Recursively merge the rest of the lists and
            // link the result to the current node
            first.next = Merge(first.next, second);
            if (first.next != null) {
                first.next.prev = first;
            }
            first.prev = null;
            return first;
        }
        else {
            // Recursively merge the rest of the lists and
            // link the result to the current node
            second.next = Merge(first, second.next);
            if (second.next != null) {
                second.next.prev = second;
            }
            second.prev = null;
            return second;
        }
    }

    // Function to perform merge sort on a doubly linked
    // list
    static Node mergeSort(Node head){
      
        // Base case: if the list is empty or has only one
        // node, it's already sorted
        if (head == null || head.next == null) {
            return head;
        }

        // Split the list into two halves
        Node second = Split(head);

        // Recursively sort each half
        head = mergeSort(head);
        second = mergeSort(second);

        // Merge the two sorted halves
        return Merge(head, second);
    }

    static void PrintList(Node head) {
        Node curr = head;
        while (curr != null) {
            Console.Write(curr.data + " ");
            curr = curr.next;
        }
        Console.WriteLine();
    }

    static void Main(string[] args) {
      
      	// Create a hard-coded doubly linked list:
  		// 10 <-> 8 <-> 5 <-> 2
        Node head = new Node(10);
        head.next = new Node(8);
        head.next.prev = head;
        head.next.next = new Node(5);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(2);
        head.next.next.next.prev = head.next.next;

        head = mergeSort(head);
      
        PrintList(head);
    }
}
JavaScript
// Javascript Program for merge sort
// on doubly linked list
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

// Function to split the doubly linked
// list into two halves
function split(head) {
    let fast = head;
    let slow = head;

    // Move fast pointer two steps and slow 
    // pointer one step until fast reaches the end
    while (fast !== null && fast.next !== null
           && fast.next.next !== null) {
        fast = fast.next.next;
        slow = slow.next;
    }

    // Split the list into two halves
    let temp = slow.next;
    slow.next = null;
    if (temp !== null) {
        temp.prev = null;
    }
    return temp;
}

// Function to merge two sorted doubly linked lists
function merge(first, second) {

    // If either list is empty, return the other list
    if (first === null)
        return second;
    if (second === null)
        return first;

    // Pick the smaller value between first and second nodes
    if (first.data < second.data) {
    
        // Recursively merge the rest of the lists and link
        // the result to the current node
        first.next = merge(first.next, second);
        if (first.next !== null) {
            first.next.prev = first;
        }
        first.prev = null;
        return first;
    }
    else {
        // Recursively merge the rest of the lists and link
        // the result to the current node
        second.next = merge(first, second.next);
        if (second.next !== null) {
            second.next.prev = second;
        }
        second.prev = null;
        return second;
    }
}

// Function to perform merge sort on a 
// doubly linked list
function mergeSort(head) {

    // Base case: if the list is empty or has only one node,
    // it's already sorted
    if (head === null || head.next === null) {
        return head;
    }

    // Split the list into two halves
    let second = split(head);

    // Recursively sort each half
    head = mergeSort(head);
    second = mergeSort(second);

    // Merge the two sorted halves
    return merge(head, second);
}

function printList(head) {
    let curr = head;
    while (curr !== null) {
        console.log(curr.data + " ");
        curr = curr.next;
    }
}

// Create a hard-coded doubly linked list:
// 10 <-> 8 <-> 5 <-> 2
let head = new Node(10);
head.next = new Node(8);
head.next.prev = head;
head.next.next = new Node(5);
head.next.next.prev = head.next;
head.next.next.next = new Node(2);
head.next.next.next.prev = head.next.next;

head = mergeSort(head);

printList(head);

Output
2 5 8 10 

Time Complexity: O(n Log n)  
Auxiliary Space: O(1)

Comment