QuickSort on Doubly Linked List (original) (raw)

Last Updated : 23 Jul, 2025

Given a **doubly linked list, the task is to **sort the doubly linked list in **non-decreasing order using the **quicksort.

**Examples:

**Input: head: 5<->3<->4<->1<->2
**Output: 1<->2<->3<->4<->5
**Explanation: Doubly Linked List after sorting using quicksort technique is 1<->2<->3<->4<->5

**Input: head: 1<->5<->2<->3
**Output: 1<->2<->3<->5
**Explanation: Doubly Linked List after sorting using quicksort technique is 1<->2<->3<->5

Try It Yourselfredirect icon

**Approach:

The**quicksort algorithm for a doubly linked list sorts the list by selecting a **pivot node and **partitioning the list into two **segments, nodes **less than the **pivot and nodes **greater than or equal to the pivot. The pivot is placed in its **correct position, and then the algorithm **recursively sorts the segments on either side of the pivot. This partitioning and recursive sorting continue until the entire list is sorted. The process efficiently handles the doubly linked list by adjusting pointers to maintain the list structure throughout the sorting operation.

Below is the implementation of the above approach:

C++ `

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

``

**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.