QuickSort on Singly Linked List

Last Updated : 3 May, 2026

Given a linked list, apply the Quick sort algorithm to sort the linked list. To sort the Linked list change pointers rather than swapping data.

Example:

Input:

2056957888

Output :

2056957889


Input: 

2056957890

Output: 

2056957891
Try It Yourself
redirect icon

Quick Sort follows these steps.

  • Selecting a pivot from the linked list, typically the last node.
  • The linked list is then partitioned such that all elements smaller than the pivot are placed on the left, while those greater than the pivot are placed on the right.
  • Once the partitioning is complete, the algorithm recursively applies the same process to the left and right linked lists.
  • The sorted left list, pivot and right list are combined to get the complete sorted list.
C++
#include <iostream>
using namespace std;

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

void printList(Node* curr) {
    while (curr != nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

// Returns the last node of the list
Node* getTail(Node* cur) {
    while (cur != nullptr && cur->next != nullptr)
        cur = cur->next;
    return cur;
}

// Partitions the list taking the first element as the pivot
Node* partition(Node* head, Node* tail) {
  
  	// Select the first node as the pivot node
    Node* pivot = head;
  
    // 'pre' and 'curr' are used to shift all 
  	// smaller nodes' data to the left side of the pivot node
    Node* pre = head;
    Node* curr = head;

    // Traverse the list until you reach the node after the tail
    while (curr != tail->next) {
        
        if (curr->data < pivot->data) {
			swap(curr->data, pre->next->data);
          
          	// Move 'pre' to the next node
            pre = pre->next;
        }
        
      	// Move 'curr' to the next node
        curr = curr->next;
    }
    
    swap(pivot->data, pre->data);
    
  	// Return 'pre' as the new pivot
    return pre;
}

// Helper function for quick sort
void quickSortHelper(Node* head, Node* tail) {
  
    // Base case: if the list is empty or consists of a single node
    if (head == nullptr || head == tail) {
        return;
    }
    
  	// Call partition to find the pivot node
    Node* pivot = partition(head, tail);
    
  	// Recursive call for the left part of the list (before the pivot)
    quickSortHelper(head, pivot);
    
  	// Recursive call for the right part of the list (after the pivot)
    quickSortHelper(pivot->next, tail);
}

// The main function for quick sort. This is a wrapper over quickSortHelper
Node* quickSort(Node* head) {
    
    Node* tail = getTail(head);
    
  	// Call the helper function to sort the list
    quickSortHelper(head, tail);
    return head;
}

int main() {
  
    // Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
    Node* head = new Node(30);
    head->next = new Node(3);
    head->next->next = new Node(4);
    head->next->next->next = new Node(20);
    head->next->next->next->next = new Node(5);

    head = quickSort(head);
    printList(head);

    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
};

void printList(struct Node* curr) {
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");
}

// Returns the last node of the list
struct Node* getTail(struct Node* cur) {
    while (cur != NULL && cur->next != NULL)
        cur = cur->next;
    return cur;
}

// Partitions the list taking the first element as the pivot
struct Node* partition(struct Node* head,struct Node* tail) {
    
  	// Select the first node as the pivot node
    struct Node* pivot = head;
  
    // 'pre' and 'curr' are used to shift all 
    // smaller nodes' data to the left side of the pivot node
   struct Node* pre = head;
   struct Node* curr = head;

    // Traverse the list until you reach the node after the tail
    while (curr != tail->next) {
        
      	// If current node's data is less than the pivot's data
        if (curr->data < pivot->data) {
            
          	// Swap the data between 'curr' and 'pre->next'
            int temp = curr->data;
            curr->data = pre->next->data;
            pre->next->data = temp;
            
            // Move 'pre' to the next node
            pre = pre->next;
        }
        // Move 'curr' to the next node
        curr = curr->next;
    }
    
    // Swap the pivot's data with 'pre' data
    int currData = pivot->data;
    pivot->data = pre->data;
    pre->data = currData;
    
    // Return 'pre' as the new pivot
    return pre;
}

// Helper function for quick sort
void quickSortHelper(struct Node* head, struct Node* tail) {
  
    // Base case: if the list is empty or consists of a single node
    if (head == NULL || head == tail) {
        return;
    }
    
    // Call partition to find the pivot node
   struct Node* pivot = partition(head, tail);
    
    // Recursive call for the left part 
  	// of the list (before the pivot)
    quickSortHelper(head, pivot);
    
    // Recursive call for the right part 
  	// of the list (after the pivot)
    quickSortHelper(pivot->next, tail);
}

// The main function for quick sort. This is a
// wrapper over quickSortHelper
struct Node* quickSort(struct Node* head) {
  
    // Find the tail of the list
    struct Node* tail = getTail(head);
    
    // Call the helper function to sort the list
    quickSortHelper(head, tail);
    return head;
}

struct Node* createNode(int x) {
    struct Node* newNode = 
      (struct Node*)malloc(sizeof(struct Node));
    newNode->data = x;
    newNode->next = NULL;
    return newNode;
}

int main() {
  
    // Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
    struct Node* head = createNode(30);
    head->next = createNode(3);
    head->next->next = createNode(4);
    head->next->next->next = createNode(20);
    head->next->next->next->next = createNode(5);

    head = quickSort(head);
    printList(head);

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

class GfG {
    
    static void printList(Node curr) {
        while (curr != null) {
            System.out.print(curr.data + " ");
            curr = curr.next;
        }
        System.out.println();
    }

    // Returns the last node of the list
    static Node getTail(Node cur) {
        while (cur != null && cur.next != null)
            cur = cur.next;
        return cur;
    }

    // Partitions the list taking the first element as the pivot
    static Node partition(Node head, Node tail) {
        
        // Select the first node as the pivot node
        Node pivot = head;
        
        // 'pre' and 'curr' are used to shift all 
        // smaller nodes' data to the left side of the pivot node
        Node pre = head;
        Node curr = head;

        // Traverse the list until you reach the node after the tail
        while (curr != tail.next) {
            
            // If current node's data is less than the pivot's data
            if (curr.data < pivot.data) {
                
                int temp = curr.data;
                curr.data = pre.next.data;
                pre.next.data = temp;
                
                // Move 'pre' to the next node
                pre = pre.next;
            }
            
            // Move 'curr' to the next node
            curr = curr.next;
        }
        
        // Swap the pivot's data with 'pre' data
        int currData = pivot.data;
        pivot.data = pre.data;
        pre.data = currData;
        
        // Return 'pre' as the new pivot
        return pre;
    }

    // Helper function for quick sort
    static void quickSortHelper(Node head, Node tail) {
      
        // Base case: if the list is empty or consists of a single node
        if (head == null || head == tail) {
            return;
        }
        
        // Call partition to find the pivot node
        Node pivot = partition(head, tail);
        
        // Recursive call for the left part of 
      	// the list (before the pivot)
        quickSortHelper(head, pivot);
        
        // Recursive call for the right part of 
      	// the list (after the pivot)
        quickSortHelper(pivot.next, tail);
    }

    // The main function for quick sort. 
  	// This is a wrapper over quickSortHelper
    static Node quickSort(Node head) {
        
        // Find the tail of the list
        Node tail = getTail(head);
        
        // Call the helper function to sort the list
        quickSortHelper(head, tail);
        return head;
    }

    public static void main(String[] args) {
      
        // Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
        Node head = new Node(30);
        head.next = new Node(3);
        head.next.next = new Node(4);
        head.next.next.next = new Node(20);
        head.next.next.next.next = new Node(5);

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

def printList(curr):
    while curr:
        print(curr.data, end=" ")
        curr = curr.next
    print()

# Returns the last node of the list
def getTail(cur):
    while cur and cur.next:
        cur = cur.next
    return cur

# Partitions the list taking the first element as the pivot
def partition(head, tail):
  
    # Select the first node as the pivot node
    pivot = head

    # 'pre' and 'curr' are used to shift all
    # smaller nodes' data to the left side of the pivot node
    pre = head
    curr = head

    # Traverse the list until you reach the node after the tail
    while curr != tail.next:
        
        # If current node's data is less than the pivot's data
        if curr.data < pivot.data:
            
            # Swap the data between 'curr' and 'pre.next'
            curr.data, pre.next.data = pre.next.data, curr.data
            
            pre = pre.next
        
        curr = curr.next

    # Swap the pivot's data with 'pre' data
    pivot.data, pre.data = pre.data, pivot.data
    
    # Return 'pre' as the new pivot
    return pre

def quickSortHelper(head, tail):
  
    # Base case: if the list is empty or consists of a single node
    if head is None or head == tail:
        return
    
    # Call partition to find the pivot node
    pivot = partition(head, tail)

    # Recursive call for the left part of the list (before the pivot)
    quickSortHelper(head, pivot)

    # Recursive call for the right part of the list (after the pivot)
    quickSortHelper(pivot.next, tail)

# The main function for quick sort.
# This is a wrapper over quickSortHelper
def quickSort(head):
  
    # Find the tail of the list
    tail = getTail(head)
    
    # Call the helper function to sort the list
    quickSortHelper(head, tail)
    return head

if __name__ == "__main__":
  
    # Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
    head = Node(30)
    head.next = Node(3)
    head.next.next = Node(4)
    head.next.next.next = Node(20)
    head.next.next.next.next = Node(5)

    head = quickSort(head)
    printList(head)
C#
using System;
class Node {
    public int Data;
    public Node next;

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

class GfG {
  
    static void PrintList(Node curr) {
        while (curr != null) {
            Console.Write(curr.Data + " ");
            curr = curr.next;
        }
        Console.WriteLine();
    }

    // Returns the last node of the list
    static Node GetTail(Node cur) {
        while (cur != null && cur.next != null)
            cur = cur.next;
        return cur;
    }

    // Partitions the list taking the first element as the pivot
    static Node Partition(Node head, Node tail) {
      
        // Select the first node as the pivot node
        Node pivot = head;

        // 'pre' and 'curr' are used to shift all
        // smaller nodes' data to the left side of the pivot node
        Node pre = head;
        Node curr = head;

        // Traverse the list until you reach the node after the tail
        while (curr != tail.next) {
          
            // If current node's data is less than the pivot's data
            if (curr.Data < pivot.Data) {
              
                // Swap the data between 'curr' and 'pre->Next'
                int temp = curr.Data;
                curr.Data = pre.next.Data;
                pre.next.Data = temp;

                // Move 'pre' to the next node
                pre = pre.next;
            }

            // Move 'curr' to the next node
            curr = curr.next;
        }

        // Swap the pivot's data with 'pre' data
        int currData = pivot.Data;
        pivot.Data = pre.Data;
        pre.Data = currData;

        // Return 'pre' as the new pivot
        return pre;
    }

    // Helper function for quick sort
    static void QuickSortHelper(Node head, Node tail) {

        // Base case: if the list is empty or consists of a single node
        if (head == null || head == tail) {
            return;
        }

        // Call partition to find the pivot node
        Node pivot = Partition(head, tail);

        // Recursive call for the left 
      	// part of the list (before the pivot)
        QuickSortHelper(head, pivot);

        // Recursive call for the right part 
      	// of the list (after the pivot)
        QuickSortHelper(pivot.next, tail);
    }

    // The main function for quick sort. 
  	// This is a wrapper over QuickSortHelper
    static Node QuickSort(Node head) {
      
        // Find the tail of the list
        Node tail = GetTail(head);

        // Call the helper function to sort the list
        QuickSortHelper(head, tail);
        return head;
    }

    static void Main() {
      
        // Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
        Node head = new Node(30);
        head.next = new Node(3);
        head.next.next = new Node(4);
        head.next.next.next = new Node(20);
        head.next.next.next.next = new Node(5);

        head = QuickSort(head);
        PrintList(head);
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.next = null;
    }
}

function printList(curr) {
    while (curr) {
        console.log(curr.data + " ");
        curr = curr.next;
    }
    console.log();
}

// Returns the last node of the list
function getTail(cur) {
    while (cur && cur.next) {
        cur = cur.next;
    }
    return cur;
}

// Partitions the list taking the first element as the pivot
function partition(head, tail) {

    // Select the first node as the pivot node
    let pivot = head;

    // 'pre' and 'curr' are used to shift all 
    // smaller nodes' data to the left side of the pivot node
    let pre = head;
    let curr = head;

    // Traverse the list until you reach the node after the tail
    while (curr !== tail.next) {
    
        // If current node's data is less than the pivot's data
        if (curr.data < pivot.data) {
            
            // Swap the data between 'curr' and 'pre.next'
            [curr.data, pre.next.data] = [pre.next.data, curr.data];
            
            // Move 'pre' to the next node
            pre = pre.next;
        }
        
        // Move 'curr' to the next node
        curr = curr.next;
    }

    // Swap the pivot's data with 'pre' data
    [pivot.data, pre.data] = [pre.data, pivot.data];
    
    // Return 'pre' as the new pivot
    return pre;
}

// Helper function for quick sort
function quickSortHelper(head, tail) {

    // Base case: if the list is empty or 
    // consists of a single node
    if (!head || head === tail) {
        return;
    }

    // Call partition to find the pivot node
    let pivot = partition(head, tail);

    // Recursive call for the left part 
    // of the list (before the pivot)
    quickSortHelper(head, pivot);

    // Recursive call for the right part 
    // of the list (after the pivot)
    quickSortHelper(pivot.next, tail);
}

// The main function for quick sort. 
// This is a wrapper over quickSortHelper
function quickSort(head) {

    // Find the tail of the list
    let tail = getTail(head);
    
    // Call the helper function to sort the list
    quickSortHelper(head, tail);
    return head;
}

// Creating a linked list: 30 -> 3 -> 4 -> 20 -> 5
let head = new Node(30);
head.next = new Node(3);
head.next.next = new Node(4);
head.next.next.next = new Node(20);
head.next.next.next.next = new Node(5);

head = quickSort(head);
printList(head);

Output
3 4 5 20 30 
  • Time Complexity: O(n * log n), It takes O(n2) time in the worst case and O(n log n) in the average or best case.
  • Auxiliary Space: O(n)
Comment