Merge Sort for Doubly Linked List (original) (raw)

Last Updated : 23 Jul, 2025

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 Yourselfredirect icon

**Note: 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.

The **MergeSort function will return the node representing the **new head of the sorted doubly linked list.

Below is the implementation of above approach :

C++ `

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

#include using namespace std;

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

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

};

// 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 != 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 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 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);

}

void printList(Node *head) { Node *curr = head; while (curr != NULL) { 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);

`

**Time Complexity: O(nLogn)
**Auxiliary Space: O(1)

**Related Articles: