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>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};// Function to split the singly linked list into two halvesNode*split(Node*head){Node*fast=head;Node*slow=head;// Move fast pointer two steps and slow pointer// one step until fast reaches the endwhile(fast!=nullptr&&fast->next!=nullptr){fast=fast->next->next;if(fast!=nullptr){slow=slow->next;}}// Split the list into two halvesNode*temp=slow->next;slow->next=nullptr;returntemp;}// Function to merge two sorted singly linked listsNode*merge(Node*first,Node*second){// If either list is empty, return the other listif(first==nullptr)returnsecond;if(second==nullptr)returnfirst;// Pick the smaller value between first and second nodesif(first->data<second->data){// Recursively merge the rest of the lists and// link the result to the current nodefirst->next=merge(first->next,second);returnfirst;}else{// Recursively merge the rest of the lists// and link the result to the current nodesecond->next=merge(first,second->next);returnsecond;}}// Function to perform merge sort on a singly linked listNode*mergeSort(Node*head){// Base case: if the list is empty or has only one node, // it's already sortedif(head==nullptr||head->next==nullptr)returnhead;// Split the list into two halvesNode*second=split(head);// Recursively sort each halfhead=mergeSort(head);second=mergeSort(second);// Merge the two sorted halvesreturnmerge(head,second);}voidprintList(Node*head){Node*curr=head;while(curr!=nullptr){cout<<curr->data<<" ";if(curr->next){cout<<"-> ";}curr=curr->next;}cout<<endl;}intmain(){// Create a hard-coded singly linked list:// 9 -> 8 -> 5 -> 2Node*head=newNode(9);head->next=newNode(8);head->next->next=newNode(5);head->next->next->next=newNode(2);head=mergeSort(head);printList(head);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}// Function to split the singly linked list into two halvesclassGfG{staticNodesplit(Nodehead){Nodefast=head;Nodeslow=head;// Move fast pointer two steps and slow pointer// one step until fast reaches the endwhile(fast!=null&&fast.next!=null){fast=fast.next.next;if(fast!=null){slow=slow.next;}}// Split the list into two halvesNodetemp=slow.next;slow.next=null;returntemp;}// Function to merge two sorted singly linked listsstaticNodemerge(Nodefirst,Nodesecond){// If either list is empty, return the other listif(first==null)returnsecond;if(second==null)returnfirst;// Pick the smaller value between first and second nodesif(first.data<second.data){// Recursively merge the rest of the lists and// link the result to the current nodefirst.next=merge(first.next,second);returnfirst;}else{// Recursively merge the rest of the lists// and link the result to the current nodesecond.next=merge(first,second.next);returnsecond;}}// Function to perform merge sort on a singly linked liststaticNodemergeSort(Nodehead){// Base case: if the list is empty or has only one node, // it's already sortedif(head==null||head.next==null){returnhead;}// Split the list into two halvesNodesecond=split(head);// Recursively sort each halfhead=mergeSort(head);second=mergeSort(second);// Merge the two sorted halvesreturnmerge(head,second);}staticvoidprintList(Nodehead){Nodecurr=head;while(curr!=null){System.out.print(curr.data+" ");if(curr.next!=null){System.out.print("-> ");}curr=curr.next;}System.out.println();}publicstaticvoidmain(String[]args){// Create a hard-coded singly linked list:// 9 -> 8 -> 5 -> 2Nodehead=newNode(9);head.next=newNode(8);head.next.next=newNode(5);head.next.next.next=newNode(2);head=mergeSort(head);printList(head);}}
Python
classNode:def__init__(self,x):self.data=xself.next=Nonedefsplit(head):fast=headslow=head# Move fast pointer two steps and slow pointer# one step until fast reaches the endwhilefastandfast.next:fast=fast.next.nextiffast:slow=slow.next# Split the list into two halvessecond=slow.nextslow.next=Nonereturnseconddefmerge(first,second):# If either list is empty, return the other listifnotfirst:returnsecondifnotsecond:returnfirst# Pick the smaller value between first and second nodesiffirst.data<second.data:first.next=merge(first.next,second)returnfirstelse:second.next=merge(first,second.next)returnseconddefmergeSort(head):# Base case: if the list is empty or has only one node, # it's already sortedifnotheadornothead.next:returnhead# Split the list into two halvessecond=split(head)# Recursively sort each halfhead=mergeSort(head)second=mergeSort(second)# Merge the two sorted halvesreturnmerge(head,second)defprintList(head):curr=headwhilecurrisnotNone:print(curr.data,end=" ")ifcurr.next:print("->",end=" ")curr=curr.nextprint()if__name__=="__main__":# Create a hard-coded singly linked list:# 9 -> 8 -> 5 -> 2head=Node(9)head.next=Node(8)head.next.next=Node(5)head.next.next.next=Node(2)head=mergeSort(head)printList(head)
C#
usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGFG{// Split the linked list into two halvesstaticNodeSplit(Nodehead){Nodeslow=head;Nodefast=head;while(fast!=null&&fast.next!=null){fast=fast.next.next;if(fast!=null){slow=slow.next;}}Nodesecond=slow.next;slow.next=null;returnsecond;}// Merge two sorted linked listsstaticNodeMerge(Nodefirst,Nodesecond){if(first==null)returnsecond;if(second==null)returnfirst;if(first.data<second.data){first.next=Merge(first.next,second);returnfirst;}else{second.next=Merge(first,second.next);returnsecond;}}// Sort the linked list using Merge SortpublicNodemergeSort(Nodehead){if(head==null||head.next==null)returnhead;Nodesecond=Split(head);head=mergeSort(head);second=mergeSort(second);returnMerge(head,second);}staticvoidPrintList(Nodehead){Nodecurr=head;while(curr!=null){Console.Write(curr.data);if(curr.next!=null)Console.Write(" -> ");curr=curr.next;}Console.WriteLine();}publicstaticvoidMain(){// Create a linked list: 9 -> 8 -> 5 -> 2Nodehead=newNode(9);head.next=newNode(8);head.next.next=newNode(5);head.next.next.next=newNode(2);GFGobj=newGFG();head=obj.mergeSort(head);PrintList(head);}}
JavaScript
// JavaScript program for merge sort on singly linked listclassNode{constructor(x){this.data=x;this.next=null;}}// Function to split the singly linked list into two halvesfunctionsplit(head){letfast=head;letslow=head;// Move fast pointer two steps and slow pointer// one step until fast reaches the endwhile(fast&&fast.next){fast=fast.next.next;if(fast){slow=slow.next;}}// Split the list into two halvesletsecond=slow.next;slow.next=null;returnsecond;}// Function to merge two sorted singly linked listsfunctionmerge(first,second){// If either list is empty, return the other listif(!first)returnsecond;if(!second)returnfirst;// Pick the smaller value between first and second nodesif(first.data<second.data){first.next=merge(first.next,second);returnfirst;}else{second.next=merge(first,second.next);returnsecond;}}// Function to perform merge sort on a singly linked listfunctionmergeSort(head){// Base case: if the list is empty or has only one node,// it's already sortedif(!head||!head.next)returnhead;// Split the list into two halvesletsecond=split(head);// Recursively sort each halfhead=mergeSort(head);second=mergeSort(second);// Merge the two sorted halvesreturnmerge(head,second);}functionprintList(head){letcurr=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 -> 2lethead=newNode(9);head.next=newNode(8);head.next.next=newNode(5);head.next.next.next=newNode(2);head=mergeSort(head);printList(head);