Merge Sort for Linked Lists (original) (raw)

Last Updated : 26 Aug, 2025

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

**Examples:

**Input:

blobid2_1756114643

**Output:

blobid3_1756114660

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

**Input:

blobid0_1756114630

**Output:

blobid1_1756114636

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

Try It Yourselfredirect icon

**Approach:

The prerequisite for this problem is Merge Sort. Here we have to maintain a **MergeSort function that sorts the list in three steps:

  1. **Split the List into Two Halves: Use two pointers, **fast and **slow, starting at the **head. Move **fast two steps and **slow one step. When **fast reaches the end, **slow is at the midpoint. Split the list into two halves: the first half from **head to just before **slow, and the second from **slow->next to the end. Set **slow->next to NULL.
  2. **Apply MergeSort Recursively: Recursively call **MergeSort() on both halves. The base case is when the list is empty (**head == NULL) or has one node (**head->next == NULL), in which case return the list as is.
  3. **Merge the Two Sorted Halves: After sorting both halves, call **merge() to merge them by comparing nodes and linking accordingly. Append any remaining nodes from the exhausted half. Finally, returns the new **head of the sorted list.

C++ `

#include 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#

// C# program for merge sort on singly linked list

using System;

class Node { public int data; public Node next; public 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) { Console.Write(curr.data + " "); if (curr.next != null) { Console.Write("-> "); } curr = curr.next; } Console.WriteLine(); }

public static void 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);
}

}

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);

`

**Time Complexity: O(n*log(n))
**Auxiliary Space: O(logn)