QuickSort on Doubly Linked List

Last Updated : 23 Jun, 2026

Given the head of a doubly linked list, sort the linked list using the Quick Sort algorithm and return the head of the sorted list.

Examples:

Input: head: 4 -> 2 -> 9

blobid0_1778935519

Output: 2 -> 4 -> 9

blobid1_1778935540


Explanation: After sorting output will look like this 2 -> 4 -> 9.

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++
// C++ program to sort a doubly linked list 
// using quicksort
#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node* prev;

    Node(int x) {
        data = x;
        next = nullptr;
        prev = nullptr;
    }
};

// Function to swap the data of two nodes
void swap(Node* a, Node* b) {
  
    // Swap the data in the nodes
    int temp = a->data;
    a->data = b->data;
    b->data = temp;
}

// Function to partition the list and find pivot
Node* partition(Node* low, Node* high) {
  
    // Set pivot to the high node
    int pivot = high->data;

    // Pointer to place smaller elements
    Node* i = low->prev;

    // Traverse the list to rearrange nodes
    for (Node* j = low; j != high; j = j->next) {
        
        // If current node's data is less than or 
        // equal to the pivot
        if (j->data <= pivot) {
            
            // Move i forward and swap with j
            i = (i == nullptr) ? low : i->next;
            swap(i, j);
        }
    }

    // Move i to the correct pivot position
    i = (i == nullptr) ? low : i->next;
  
    // Swap pivot with i's data
    swap(i, high);

    return i;
}

// Recursive function to apply quicksort
void quickSort(Node* low, Node* high) {
  
    // Base case: if the list has one element or 
    // invalid range
    if (low != nullptr && high != nullptr 
        && low != high && low != high->next) {
      
        // Find the partition node (pivot)
        Node* pivot = partition(low, high);

        // Recursively sort the left half
        quickSort(low, pivot->prev);

        // Recursively sort the right half
        quickSort(pivot->next, high);
    }
}

// Function to get the last node of the list
Node* getLastNode(Node* head) {
  
    // Traverse to the end of the list
    while (head != nullptr && head->next != nullptr) {
        head = head->next;
    }
  
    return head;
}

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

int main() {
  
    // Create a hard-coded doubly linked list:
    // 5 <-> 3 <-> 4 <-> 1 <-> 2
    Node* head = new Node(5);
    head->next = new Node(3);
    head->next->prev = head;
    head->next->next = new Node(4);
    head->next->next->prev = head->next;
    head->next->next->next = new Node(1);
    head->next->next->next->prev = 
                     head->next->next;
    head->next->next->next->next = new Node(2);
    head->next->next->next->next->prev = 
                     head->next->next->next;

    Node* last = getLastNode(head);
    quickSort(head, last);
    printList(head);

    return 0;
}
C
// C program to sort a doubly linked list
// using quicksort
#include <stdio.h>
#include <stdlib.h>

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

// Function to swap the data of two nodes
void swap(struct Node* a, struct Node* b) {
  
    // Swap the data in the nodes
    int temp = a->data;
    a->data = b->data;
    b->data = temp;
}

// Function to partition the list and find pivot
struct Node* partition(struct Node* low,
                       struct Node* high) {

    // Set pivot to the high node
    int pivot = high->data;

    // Pointer to place smaller elements
    struct Node* i = low->prev;

    // Traverse the list to rearrange nodes
    for (struct Node* j = low; j != high;
         j = j->next) {
      
        // If current node's data is less than 
        // or equal to the pivot
        if (j->data <= pivot) {
            
            // Move `i` forward and swap with `j`
            i = (i == NULL) ? low : i->next;
            swap(i, j);
        }
    }

    // Move `i` to the correct pivot position
    i = (i == NULL) ? low : i->next;
    
    // Swap pivot with `i`'s data
    swap(i, high);

    return i;
}

// Recursive function to apply quicksort
void quickSort(struct Node* low, struct Node* high) {
  
    // Base case: if the list has one element or 
    // invalid range
    if (low != NULL && high != NULL 
        && low != high && low != high->next) {
      
        // Find the partition node (pivot)
        struct Node* pivot = partition(low, high);

        // Recursively sort the left half
        quickSort(low, pivot->prev);

        // Recursively sort the right half
        quickSort(pivot->next, high);
    }
}

// Function to get the last node of the list
struct Node* getLastNode(struct Node* head) {
  
    // Traverse to the end of the list
    while (head != NULL && head->next != NULL) {
        head = head->next;
    }
    return head;
}

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

struct Node* createNode(int new_data) {
    struct Node* new_node =
      (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = NULL;
    new_node->prev = NULL;
    return new_node;
}

int main() {

    // Create a hard-coded doubly linked list:
    // 5 <-> 3 <-> 4 <-> 1 <-> 2
    struct Node* head = createNode(5);
    head->next = createNode(3);
    head->next->prev = head;
    head->next->next = createNode(4);
    head->next->next->prev = head->next;
    head->next->next->next = createNode(1);
    head->next->next->next->prev = 
                     head->next->next;
    head->next->next->next->next = createNode(2);
    head->next->next->next->next->prev = 
                     head->next->next->next;

    struct Node* last = getLastNode(head);

    quickSort(head, last);
  
    printList(head);

    return 0;
}
Java
// Java program to sort a doubly linked list
// using quicksort
class Node {
    int data;
    Node next, prev;
  
    Node(int x) {
        data = x;
        next = null;
        prev = null;
    }
}

public class GfG {

    // Function to swap data of two nodes
    static void swap(Node a, Node b) {

        // Swap data between `a` and `b`
        int temp = a.data;
        a.data = b.data;
        b.data = temp;
    }

    // Function to partition the list around pivot
    static Node partition(Node low, Node high) {

        // Set pivot to the data of `high` node
        int pivot = high.data;

        // Pointer to place smaller elements
        Node i = low.prev;

        // Traverse list from `low` to `high`
        for (Node j = low; j != high; j = j.next) {

            // If current data is <= pivot
            if (j.data <= pivot) {
                
                // Move `i` forward and swap with `j`
                i = (i == null) ? low : i.next;
                swap(i, j);
            }
        }

        // Move `i` to correct pivot position
        i = (i == null) ? low : i.next;

        // Swap pivot data with `i`'s data
        swap(i, high);

        return i;
    }

    // Recursive quicksort function
    static void quickSort(Node low, Node high) {

        // Base case: stop recursion when invalid range
        if (low != null && high != null &&
            low != high && low != high.next) {

            // Partition the list and get the pivot node
            Node pivot = partition(low, high);

            // Recursively sort the left half
            quickSort(low, pivot.prev);

            // Recursively sort the right half
            quickSort(pivot.next, high);
        }
    }

    // Function to get the last node of the list
    static Node getLastNode(Node head) {

        // Traverse to the end of the list
        while (head != null && head.next != null) {
            head = head.next;
        }
        return head;
    }

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

    public static void main(String[] args) {

        // Create a hard-coded doubly linked list:
        // 5 <-> 3 <-> 4 <-> 1 <-> 2
        Node head = new Node(5);
        head.next = new Node(3);
        head.next.prev = head;
        head.next.next = new Node(4);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(1);
        head.next.next.next.prev = head.next.next;
        head.next.next.next.next = new Node(2);
        head.next.next.next.next.prev = 
                                head.next.next.next;


        Node last = getLastNode(head);

        quickSort(head, last);

        printList(head);
    }
}
Python
# Python program to sort a doubly linked list
# using quicksort
class Node:
    
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

# Function to swap data between two nodes
def swap(a, b):
    
    # Swap the data between node `a` and node `b`
    a.data, b.data = b.data, a.data

# Partition function for quicksort
def partition(low, high):
    
    # Set pivot as the data of `high` node
    pivot = high.data

    # Pointer to place smaller elements
    i = low.prev

    # Traverse from `low` to `high`
    curr = low
    while curr != high:
        
        # If current node's data is <= pivot
        if curr.data <= pivot:
            
            # Move `i` forward and swap with `curr`
            i = low if i is None else i.next
            swap(i, curr)
        
        curr = curr.next

    # Move `i` to the correct pivot position
    i = low if i is None else i.next

    # Swap pivot data with `i`'s data
    swap(i, high)
    
    return i

# Recursive quicksort function
def quick_sort(low, high):
    
    # Base case: stop when invalid range
    if low and high and low != high and low != high.next:
        
        # Partition the list and get the pivot node
        pivot = partition(low, high)

        # Recursively sort the left half
        quick_sort(low, pivot.prev)

        # Recursively sort the right half
        quick_sort(pivot.next, high)

# Function to get the last node of the list
def get_last_node(head):
    
    # Traverse to the last node
    while head and head.next:
        head = head.next
    return head

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

if __name__ == '__main__':
    
    # Create a hard-coded doubly linked list:
    # 5 <-> 3 <-> 4 <-> 1 <-> 2
    head = Node(5)
    head.next = Node(3)
    head.next.prev = head
    head.next.next = Node(4)
    head.next.next.prev = head.next
    head.next.next.next = Node(1)
    head.next.next.next.prev = head.next.next
    head.next.next.next.next = Node(2)
    head.next.next.next.next.prev = head.next.next.next

    last_node = get_last_node(head)

    quick_sort(head, last_node)

    print_list(head)
C#
// C# program to sort a singly linked list 
// using quicksort 
using System;

public class Node {
  
    public int data;
    public Node next;
  
    public Node(int new_data) {
        data = new_data;
        next = null;
    }
}

class GfG {
  
    // Function to swap data between two nodes
    static void Swap(Node a, Node b) {
        
        // Swap data between node `a` and node `b`
        int temp = a.data;
        a.data = b.data;
        b.data = temp;
    }

    // Partition function for quicksort
    static Node Partition(Node low, Node high) {
        
        // Set pivot as the data of `high` node
        int pivot = high.data;

        // Pointer to place smaller elements
        Node i = low;

        // Traverse from `low` to `high`
        Node curr = low;
        while (curr != high) {
            
            // If current node's data is <= pivot
            if (curr.data <= pivot) {
                
                // Swap data between `i` and `curr`
                Swap(i, curr);
                
                // Move `i` forward
                i = i.next;
            }
            curr = curr.next;
        }

        // Swap pivot data with `i`'s data
        Swap(i, high);
        return i;
    }

    // Recursive quicksort function
    static void QuickSort(Node low, Node high) {
        
        // Base case: stop when invalid range
        if (low != high && low != null && high != null) {
            
            // Partition the list and get the pivot node
            Node pivot = Partition(low, high);

            // Recursively sort the left half
            Node beforePivot = low;
            while (beforePivot != null
                    && beforePivot.next != pivot) {
                beforePivot = beforePivot.next;
            }

            // Sort left of pivot only if exists
            if (beforePivot != null && beforePivot != pivot)
                QuickSort(low, beforePivot);

            // Recursively sort the right half
            if (pivot != null && pivot.next != high)
                QuickSort(pivot.next, high);
        }
    }

    // Function to get the last node of the list
    static Node GetLastNode(Node head) {
        
        // Traverse the list to find the last node
        while (head != null && head.next != null) {
            head = head.next;
        }
        return head;
    }

    static void PrintList(Node node) {
        Node curr = node;
        while (curr != null) {
            Console.Write(" " + curr.data);
            curr = curr.next;
        }
    }

    static void Main(string[] args) {
        
        // Create a hard-coded linked list:
        // 5 -> 3 -> 4 -> 1 -> 2
        Node head = new Node(5);
        head.next = new Node(3);
        head.next.next = new Node(4);
        head.next.next.next = new Node(1);
        head.next.next.next.next = new Node(2);

        Node lastNode = GetLastNode(head);

        QuickSort(head, lastNode);

        PrintList(head);
    }
}
JavaScript
// JavaScript program to sort a doubly linked list
// using quicksort
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

// Function to swap the data between two nodes
function swap(a, b) {
    let temp = a.data;
    a.data = b.data;
    b.data = temp;
}

// Partition function for quicksort
function partition(low, high) {

    // Set pivot as the data of `high` node
    let pivot = high.data;

    // Pointer to place smaller elements
    let i = low.prev;

    // Traverse from `low` to `high`
    for (let j = low; j !== high; j = j.next) {
        if (j.data <= pivot) {
            i = (i === null) ? low : i.next;
            swap(i, j);
        }
    }

    // Swap pivot data with `i.next`'s data
    i = (i === null) ? low : i.next;
    swap(i, high);
    return i;
}

// Recursive quicksort function
function quickSort(low, high) {
    if (low !== null && high !== null && low !== high 
                                  && low !== high.next) {
        let pivot = partition(low, high);

        // Sort left side of the pivot
        quickSort(low, pivot.prev);

        // Sort right side of the pivot
        quickSort(pivot.next, high);
    }
}

// Function to get the last node of the list
function getLastNode(head) {
    while (head !== null && head.next !== null) {
        head = head.next;
    }
    return head;
}

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

// Create a hard-coded doubly linked list:
// 5 <-> 3 <-> 4 <-> 1 <-> 2
let head = new Node(5);
head.next = new Node(3);
head.next.prev = head;
head.next.next = new Node(4);
head.next.next.prev = head.next;
head.next.next.next = new Node(1);
head.next.next.next.prev = head.next.next;
head.next.next.next.next = new Node(2);
head.next.next.next.next.prev = head.next.next.next;

let lastNode = getLastNode(head);

quickSort(head, lastNode);

printList(head);

Output
 1 2 3 4 5

Time Complexity: On average, quicksort has a time complexity of O(nlogn), where n is the number of nodes. In the worst case (e.g., already sorted list), it becomes O(n²).
Auxiliary Space: O(logn) due to the recursion stack in average cases, and O(n) in the worst case.

Comment