Merge Sort for Linked Lists

Last Updated : 18 Oct, 2026

Given a singly linked list, we need to sort the linked list in non-decreasing order using merge sort.

Examples:

Input:

blobid2_1756114643


Output:

Explanation: After sorting the given linked list , resultant will be 2 -> 5 -> 8 -> 9.

blobid3_1756114660


Input:

blobid0_1756114630


Output:

Explanation: After sorting the given linked list, the resultant matrix will be 10 -> 20 -> 30 -> 40 -> 50 ->60 ->NULL.

blobid1_1756114636


Try It Yourself
redirect icon

Merge Sort - O(n*log(n)) Time and O(log (n)) Space

Merge sort works good for Linked List as it does a sequential access for sorting and does not require an auxiliary array or list like we need for sorting an array using Merge Sort.

Merge Sort sorts a linked list by splitting it into two halves, sorting each half recursively, and merging the sorted halves. This continues until each half contains only one node, which is already sorted.

  • Split the list: Use two pointers, slow and fast, to find the middle of the linked list. Split the list into two smaller lists.
  • Sort both halves: Recursively call mergeSort() on each half until the lists are empty or contain only one node.
  • Merge the sorted halves: Compare the nodes of both sorted lists, link the smaller node first, and append any remaining nodes. Return the head of the merged, sorted list.
C++
#include <iostream>
using namespace std;

class Node {
  public:
    int data;
    Node *next;
    Node(int x) {
        data = x;
        next = nullptr;
    }
};

// Function to split the singly 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 = fast->next->next;
        if (fast != nullptr) {
            slow = slow->next;
        }
    }

    // Split the list into two halves
    Node *temp = slow->next;
    slow->next = nullptr;
    return temp;
}

// Function to merge two sorted singly 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);
        return first;
    }
    else {
        // Recursively merge the rest of the lists
        // and link the result to the current node
        second->next = merge(first, second->next);
        return second;
    }
}

// Function to perform merge sort on a singly 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 << " ";
        if(curr->next){
            cout << "-> ";
        }
        curr = curr->next;
    }
    cout << endl;
}

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

    head = mergeSort(head);
    printList(head);

    return 0;
}
Java
class Node {
    int data;
    Node next;
    Node(int x) {
        data = x;
        next = null;
    }
}

// Function to split the singly linked list into two halves
class GfG {
    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 = fast.next.next;
            if (fast != null) {
                slow = slow.next;
            }
        }

        // Split the list into two halves
        Node temp = slow.next;
        slow.next = null;
        return temp;
    }

    // Function to merge two sorted singly 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);
            return first;
        }
        else {
            // Recursively merge the rest of the lists
            // and link the result to the current node
            second.next = merge(first, second.next);
            return second;
        }
    }

    // Function to perform merge sort on a singly 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 + " ");
            if(curr.next != null){
                System.out.print("-> ");
            }
            curr = curr.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // Create a hard-coded singly linked list:
        // 9 -> 8 -> 5 -> 2
        Node head = new Node(9);
        head.next = new Node(8);
        head.next.next = new Node(5);
        head.next.next.next = new Node(2);

        head = mergeSort(head);
        printList(head);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None

def split(head):
    fast = head
    slow = head

    # Move fast pointer two steps and slow pointer
    # one step until fast reaches the end
    while fast and fast.next:
        fast = fast.next.next
        if fast:
            slow = slow.next

    # Split the list into two halves
    second = slow.next
    slow.next = None
    return second

def merge(first, second):
  
    # If either list is empty, return the other list
    if not first:
        return second
    if not second:
        return first

    # Pick the smaller value between first and second nodes
    if first.data < second.data:
        first.next = merge(first.next, second)
        return first
    else:
        second.next = merge(first, second.next)
        return second

def mergeSort(head):
  
    # Base case: if the list is empty or has only one node, 
    # it's already sorted
    if not head or not head.next:
        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=" ")
        if curr.next:
            print("->", end=" ")
        curr = curr.next
    print()


if __name__ == "__main__":
    # Create a hard-coded singly linked list:
    # 9 -> 8 -> 5 -> 2
    head = Node(9)
    head.next = Node(8)
    head.next.next = Node(5)
    head.next.next.next = Node(2)

    head = mergeSort(head)
    printList(head)
C#
using System;

class Node {
    public int data;
    public Node next;

    public Node(int x) {
        data = x;
        next = null;
    }
}

class GFG {
    // Split the linked list into two halves
    static Node Split(Node head) {
        Node slow = head;
        Node fast = head;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;

            if (fast != null) {
                slow = slow.next;
            }
        }

        Node second = slow.next;
        slow.next = null;

        return second;
    }

    // Merge two sorted linked lists
    static Node Merge(Node first, Node second) {
        if (first == null)
            return second;

        if (second == null)
            return first;

        if (first.data < second.data) {
            first.next = Merge(first.next, second);
            return first;
        } else {
            second.next = Merge(first, second.next);
            return second;
        }
    }

    // Sort the linked list using Merge Sort
    public Node mergeSort(Node head) {
        if (head == null || head.next == null)
            return head;

        Node second = Split(head);

        head = mergeSort(head);
        second = mergeSort(second);

        return Merge(head, second);
    }

    static void PrintList(Node head) {
        Node curr = head;

        while (curr != null) {
            Console.Write(curr.data);

            if (curr.next != null)
                Console.Write(" -> ");

            curr = curr.next;
        }

        Console.WriteLine();
    }

    public static void Main() {
        // Create a linked list: 9 -> 8 -> 5 -> 2
        Node head = new Node(9);
        head.next = new Node(8);
        head.next.next = new Node(5);
        head.next.next.next = new Node(2);

        GFG obj = new GFG();
        head = obj.mergeSort(head);

        PrintList(head);
    }
}
JavaScript
// JavaScript program for merge sort on singly linked list

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

// Function to split the singly 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 && fast.next) {
        fast = fast.next.next;
        if (fast) {
            slow = slow.next;
        }
    }

    // Split the list into two halves
    let second = slow.next;
    slow.next = null;
    return second;
}

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

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

    // Pick the smaller value between first and second nodes
    if (first.data < second.data) {
        first.next = merge(first.next, second);
        return first;
    }
    else {
        second.next = merge(first, second.next);
        return second;
    }
}

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

    // Base case: if the list is empty or has only one node,
    // it's already sorted
    if (!head || !head.next)
        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) {
        process.stdout.write(curr.data + " ");
        if (curr.next) {
            process.stdout.write("-> ");
        }
        curr = curr.next;
    }
    console.log();
}

// Create a hard-coded singly linked list:
// 9 -> 8 -> 5 -> 2
let head = new Node(9);
head.next = new Node(8);
head.next.next = new Node(5);
head.next.next.next = new Node(2);

head = mergeSort(head);
printList(head);

Output
2 -> 5 -> 8 -> 9 


Comment