[Naive Approach] Using Merge Sort - O(n * log n) Time and O(log n) Space
The idea is to use Merge Sort. Merge Sort is particularly suitable for linked lists because we can split the list using slow/fast pointers and merge the sorted halves using only pointer manipulation.
We recursively divide the list into smaller halves until each part contains one node. Then we merge the halves by comparing their actual values, producing a completely sorted linked list.
Find the middle of the linked list using slow and fast pointers.
Split the list into two halves.
Recursively sort both halves based on actual values.
Merge the two sorted halves by comparing node values.
Continue merging until all nodes are combined.
Return the head of the merged sorted list.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};// Merge two sorted linked lists.Node*mergeLists(Node*a,Node*b){if(a==nullptr)returnb;if(b==nullptr)returna;// Choose the smaller node.if(a->data<=b->data){a->next=mergeLists(a->next,b);returna;}else{b->next=mergeLists(a,b->next);returnb;}}// Find the middle of the linked list.Node*getMiddle(Node*head){Node*slow=head;Node*fast=head->next;while(fast!=nullptr&&fast->next!=nullptr){slow=slow->next;fast=fast->next->next;}returnslow;}// Sort the linked list using Merge Sort.Node*sortList(Node*head){// Base case.if(head==nullptr||head->next==nullptr)returnhead;// Find the middle.Node*middle=getMiddle(head);// Split the list into two halves.Node*right=middle->next;middle->next=nullptr;// Recursively sort both halves.Node*left=sortList(head);right=sortList(right);// Merge the sorted halves.returnmergeLists(left,right);}voidprintList(Node*head){while(head!=nullptr){cout<<head->data;if(head->next!=nullptr)cout<<" -> ";head=head->next;}cout<<endl;}intmain(){Node*head=newNode(0);head->next=newNode(1);head->next->next=newNode(-2);head->next->next->next=newNode(3);head->next->next->next->next=newNode(-4);head->next->next->next->next->next=newNode(5);head=sortList(head);printList(head);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}classGFG{// Merge two sorted linked lists.staticNodemergeLists(Nodea,Nodeb){if(a==null)returnb;if(b==null)returna;// Choose the smaller node.if(a.data<=b.data){a.next=mergeLists(a.next,b);returna;}else{b.next=mergeLists(a,b.next);returnb;}}// Find the middle of the linked list.staticNodegetMiddle(Nodehead){Nodeslow=head;Nodefast=head.next;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}returnslow;}// Sort the linked list using Merge Sort.staticNodesortList(Nodehead){// Base case.if(head==null||head.next==null)returnhead;// Find the middle.Nodemiddle=getMiddle(head);// Split the list into two halves.Noderight=middle.next;middle.next=null;// Recursively sort both halves.Nodeleft=sortList(head);right=sortList(right);// Merge the sorted halves.returnmergeLists(left,right);}staticvoidprintList(Nodehead){while(head!=null){System.out.print(head.data);if(head.next!=null)System.out.print(" -> ");head=head.next;}System.out.println();}publicstaticvoidmain(String[]args){Nodehead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);printList(head);}}
Python
classNode:def__init__(self,data):self.data=dataself.next=None# Merge two sorted linked lists.defmerge_lists(a,b):ifaisNone:returnbifbisNone:returna# Choose the smaller node.ifa.data<=b.data:a.next=merge_lists(a.next,b)returnaelse:b.next=merge_lists(a,b.next)returnb# Find the middle of the linked list.defget_middle(head):slow=headfast=head.nextwhilefastisnotNoneandfast.nextisnotNone:slow=slow.nextfast=fast.next.nextreturnslow# Sort the linked list using Merge Sort.defsortList(head):# Base case.ifheadisNoneorhead.nextisNone:returnhead# Find the middle.middle=get_middle(head)# Split the list into two halves.right=middle.nextmiddle.next=None# Recursively sort both halves.left=sortList(head)right=sortList(right)# Merge the sorted halves.returnmerge_lists(left,right)defprint_list(head):whileheadisnotNone:print(head.data,end="")ifhead.nextisnotNone:print(" -> ",end="")head=head.nextprint()# Driver Codeif__name__=="__main__":# Create the linked list.head=Node(0)head.next=Node(1)head.next.next=Node(-2)head.next.next.next=Node(3)head.next.next.next.next=Node(-4)head.next.next.next.next.next=Node(5)head=sortList(head)print_list(head)
C#
usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGFG{// Merge two sorted linked lists.staticNodeMergeLists(Nodea,Nodeb){if(a==null)returnb;if(b==null)returna;// Choose the smaller node.if(a.data<=b.data){a.next=MergeLists(a.next,b);returna;}else{b.next=MergeLists(a,b.next);returnb;}}// Find the middle of the linked list.staticNodeGetMiddle(Nodehead){Nodeslow=head;Nodefast=head.next;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}returnslow;}// Sort the linked list using Merge Sort.staticNodesortList(Nodehead){// Base case.if(head==null||head.next==null)returnhead;// Find the middle.Nodemiddle=GetMiddle(head);// Split the list into two halves.Noderight=middle.next;middle.next=null;// Recursively sort both halves.Nodeleft=sortList(head);right=sortList(right);// Merge the sorted halves.returnMergeLists(left,right);}staticvoidPrintList(Nodehead){while(head!=null){Console.Write(head.data);if(head.next!=null)Console.Write(" -> ");head=head.next;}Console.WriteLine();}staticvoidMain(){Nodehead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);PrintList(head);}}
JavaScript
classNode{constructor(data){this.data=data;this.next=null;}}// Merge two sorted linked lists.functionmergeLists(a,b){if(a===null)returnb;if(b===null)returna;// Choose the smaller node.if(a.data<=b.data){a.next=mergeLists(a.next,b);returna;}else{b.next=mergeLists(a,b.next);returnb;}}// Find the middle of the linked list.functiongetMiddle(head){letslow=head;letfast=head.next;while(fast!==null&&fast.next!==null){slow=slow.next;fast=fast.next.next;}returnslow;}// Sort the linked list using Merge Sort.functionsortList(head){// Base case.if(head===null||head.next===null)returnhead;// Find the middle.constmiddle=getMiddle(head);// Split the list into two halves.letright=middle.next;middle.next=null;// Recursively sort both halves.constleft=sortList(head);right=sortList(right);// Merge the sorted halves.returnmergeLists(left,right);}functionprintList(head){constresult=[];while(head!==null){result.push(head.data);head=head.next;}console.log(result.join(" -> "));}// Driver Code// Create the linked list.lethead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);printList(head);
Output
-4 -> -2 -> 0 -> 1 -> 3 -> 5
[Expected Approach] Move Negative Nodes to Front - O(n) Time and O(1) Space
Since the list is sorted by absolute values, the non-negative nodes are already in increasing order, while the negative nodes appear in decreasing actual order.
So, the idea is to traverse the list and whenever a node is smaller than the previous node, we move it to the front. Such a node must be negative, and moving all such nodes to the front reverses their order automatically.
Start with prev = head and curr = head->next.
Traverse the linked list from left to right.
If curr->data < prev->data, detach curr from its current position.
Insert curr at the beginning of the list.
Set curr back to prev and continue traversing.
Return the updated head.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};// Sort the linked list based on actual values.// The given list is already sorted by absolute values.Node*sortList(Node*head){// Handle empty or single-node list.if(head==nullptr||head->next==nullptr)returnhead;Node*prev=head;Node*curr=head->next;while(curr!=nullptr){// If current node is smaller than the previous node,// move it to the beginning of the list.if(curr->data<prev->data){// Detach curr from its current position.prev->next=curr->next;// Insert curr at the beginning.curr->next=head;head=curr;// Continue checking from prev.curr=prev;}else{// Current node is already in the correct position.prev=curr;}curr=curr->next;}returnhead;}voidprintList(Node*head){while(head!=nullptr){cout<<head->data;if(head->next!=nullptr)cout<<" -> ";head=head->next;}cout<<endl;}intmain(){Node*head=newNode(0);head->next=newNode(1);head->next->next=newNode(-2);head->next->next->next=newNode(3);head->next->next->next->next=newNode(-4);head->next->next->next->next->next=newNode(5);head=sortList(head);printList(head);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}classGFG{// Sort the linked list based on actual values.// The given list is already sorted by absolute values.staticNodesortList(Nodehead){// Handle empty or single-node list.if(head==null||head.next==null)returnhead;Nodeprev=head;Nodecurr=head.next;while(curr!=null){// If current node is smaller than the previous// node, move it to the beginning.if(curr.data<prev.data){// Detach curr from its current position.prev.next=curr.next;// Insert curr at the beginning.curr.next=head;head=curr;// Continue checking from prev.curr=prev;}else{// Current node is already in the correct// position.prev=curr;}curr=curr.next;}returnhead;}staticvoidprintList(Nodehead){while(head!=null){System.out.print(head.data);if(head.next!=null)System.out.print(" -> ");head=head.next;}System.out.println();}publicstaticvoidmain(String[]args){Nodehead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);printList(head);}}
Python
classNode:def__init__(self,data):self.data=dataself.next=None# Sort the linked list based on actual values.# The given list is already sorted by absolute values.defsortList(head):# Handle empty or single-node list.ifheadisNoneorhead.nextisNone:returnheadprev=headcurr=head.nextwhilecurrisnotNone:# If current node is smaller than the previous node,# move it to the beginning.ifcurr.data<prev.data:# Detach curr from its current position.prev.next=curr.next# Insert curr at the beginning.curr.next=headhead=curr# Continue checking from prev.curr=prevelse:# Current node is already in the correct position.prev=currcurr=curr.nextreturnheaddefprint_list(head):whileheadisnotNone:print(head.data,end="")ifhead.nextisnotNone:print(" -> ",end="")head=head.nextprint()# Driver Codeif__name__=="__main__":# Create the linked list.head=Node(0)head.next=Node(1)head.next.next=Node(-2)head.next.next.next=Node(3)head.next.next.next.next=Node(-4)head.next.next.next.next.next=Node(5)head=sortList(head)print_list(head)
C#
usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGFG{// Sort the linked list based on actual values.// The given list is already sorted by absolute values.staticNodesortList(Nodehead){// Handle empty or single-node list.if(head==null||head.next==null)returnhead;Nodeprev=head;Nodecurr=head.next;while(curr!=null){// If current node is smaller than the previous// node, move it to the beginning.if(curr.data<prev.data){// Detach curr from its current position.prev.next=curr.next;// Insert curr at the beginning.curr.next=head;head=curr;// Continue checking from prev.curr=prev;}else{// Current node is already in the correct// position.prev=curr;}curr=curr.next;}returnhead;}staticvoidPrintList(Nodehead){while(head!=null){Console.Write(head.data);if(head.next!=null)Console.Write(" -> ");head=head.next;}Console.WriteLine();}staticvoidMain(){Nodehead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);PrintList(head);}}
JavaScript
classNode{constructor(data){this.data=data;this.next=null;}}// Sort the linked list based on actual values.// The given list is already sorted by absolute values.functionsortList(head){// Handle empty or single-node list.if(head===null||head.next===null)returnhead;letprev=head;letcurr=head.next;while(curr!==null){// If current node is smaller than the previous// node, move it to the beginning.if(curr.data<prev.data){// Detach curr from its current position.prev.next=curr.next;// Insert curr at the beginning.curr.next=head;head=curr;// Continue checking from prev.curr=prev;}else{// Current node is already in the correct// position.prev=curr;}curr=curr.next;}returnhead;}functionprintList(head){letresult=[];while(head!==null){result.push(head.data);head=head.next;}console.log(result.join(" -> "));}// Driver Code// Create the linked list.lethead=newNode(0);head.next=newNode(1);head.next.next=newNode(-2);head.next.next.next=newNode(3);head.next.next.next.next=newNode(-4);head.next.next.next.next.next=newNode(5);head=sortList(head);printList(head);