Improve
Suggest changes
313 Likes
Like
Report
Try it on GfG Practice
redirect icon

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.


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<iostream>
usingnamespacestd;
classNode{
public:
intdata;
Node*next;
Node(intx){
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;
returntemp;
}
// 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)returnsecond;
if(second==nullptr)returnfirst;
// 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);
returnfirst;
}
else{
// Recursively merge the rest of the lists
// and link the result to the current node
second->next=merge(first,second->next);
returnsecond;
}
}
// 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)
returnhead;
// 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
returnmerge(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 -> 2
Node*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
class Node{
intdata;
Nodenext;
Node(intx){
data=x;
next=null;
}
}
// Function to split the singly linked list into two halves
class GfG{
staticNodesplit(Nodehead){
Nodefast=head;
Nodeslow=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
Nodetemp=slow.next;
slow.next=null;
returntemp;
}
// Function to merge two sorted singly linked lists
staticNodemerge(Nodefirst,Nodesecond){

// If either list is empty, return the other list
if(first==null)returnsecond;
if(second==null)returnfirst;
// 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);
returnfirst;
}
else{
// Recursively merge the rest of the lists
// and link the result to the current node
second.next=merge(first,second.next);
returnsecond;
}
}
// Function to perform merge sort on a singly linked list
staticNodemergeSort(Nodehead){

// Base case: if the list is empty or has only one node, 
// it's already sorted
if(head==null||head.next==null){
returnhead;
}
// Split the list into two halves
Nodesecond=split(head);
// Recursively sort each half
head=mergeSort(head);
second=mergeSort(second);
// Merge the two sorted halves
returnmerge(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 -> 2
Nodehead=newNode(9);
head.next=newNode(8);
head.next.next=newNode(5);
head.next.next.next=newNode(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
usingSystem;
classNode{
publicintdata;
publicNodenext;
publicNode(intx)
{
data=x;
next=null;
}
}
// Function to split the singly linked list into two halves
classGfG{
staticNodeSplit(Nodehead)
{
Nodefast=head;
Nodeslow=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
Nodetemp=slow.next;
slow.next=null;
returntemp;
}
// Function to merge two sorted singly linked lists
staticNodeMerge(Nodefirst,Nodesecond){
// If either list is empty, return the other list
if(first==null)
returnsecond;
if(second==null)
returnfirst;
// 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);
returnfirst;
}
else{
// Recursively merge the rest of the lists
// and link the result to the current node
second.next=Merge(first,second.next);
returnsecond;
}
}
// Function to perform merge sort on a singly linked
// list
staticNodeMergeSort(Nodehead){
// Base case: if the list is empty or has only one
// node, it's already sorted
if(head==null||head.next==null)
returnhead;
// Split the list into two halves
Nodesecond=Split(head);
// Recursively sort each half
head=MergeSort(head);
second=MergeSort(second);
// Merge the two sorted halves
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 hard-coded singly linked list:
// 9 -> 8 -> 5 -> 2
Nodehead=newNode(9);
head.next=newNode(8);
head.next.next=newNode(5);
head.next.next.next=newNode(2);
head=MergeSort(head);
PrintList(head);
}
}
JavaScript
// JavaScript program for merge sort on singly linked list
classNode{
constructor(x)
{
this.data=x;
this.next=null;
}
}
// Function to split the singly linked list into two halves
functionsplit(head)
{
letfast=head;
letslow=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
letsecond=slow.next;
slow.next=null;
returnsecond;
}
// Function to merge two sorted singly linked lists
functionmerge(first,second)
{
// If either list is empty, return the other list
if(!first)
returnsecond;
if(!second)
returnfirst;
// Pick the smaller value between first and second nodes
if(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 list
functionmergeSort(head)
{
// Base case: if the list is empty or has only one node,
// it's already sorted
if(!head||!head.next)
returnhead;
// Split the list into two halves
letsecond=split(head);
// Recursively sort each half
head=mergeSort(head);
second=mergeSort(second);
// Merge the two sorted halves
returnmerge(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 -> 2
lethead=newNode(9);
head.next=newNode(8);
head.next.next=newNode(5);
head.next.next.next=newNode(2);
head=mergeSort(head);
printList(head);

Output
2 -> 5 -> 8 -> 9 

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


Improve
Improve
Article Tags :
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

AltStyle によって変換されたページ (->オリジナル) /