QuickSort on Singly Linked List Last Updated : 04 Nov, 2024 Comments Improve Suggest changes Like Article Like Report Try it on GfG Practice 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: 5->4->1->3->2Output: 1->2->3->4->5Input: 4->3->2->1Output: 1->2->3->4Approach:The Quick Sort algorithm works by selecting a pivot element from the array, typically the last element. The array 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 subarrays. This recursive sorting continues until the entire array is sorted, with the sorted subarrays and pivot being combined to form the final sorted array.Follow the given steps to solve the problem:Call partition function to get a pivot node placed at its correct position.In the partition function, the last element is considered a pivot.Then traverse the current list and if a node has a value greater than the pivot, then move it after the tail. If the node has a smaller value, then keep it at its current position. Return pivot nodeFind the tail node of the list which is on the left side of the pivot and recur for the left listSimilarly, after the left side, recur for the list on the right side of the pivotNow return the head of the linked list after joining the left and the right list, as the whole linked list is now sorted.Below is the implementation of the above approach: C++ // C++ program for Quick Sort on Singly Linked List #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 // C program for Quick Sort on Singly Linked List #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 // Java program for Quick Sort on Singly Linked List 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 # Python program for Quick Sort on Singly Linked List 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# // C# program for Quick Sort on // Singly Linked List 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 // Javascript program for Quick Sort on Singly Linked List 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); Output3 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 More infoAdvertise with us Next Article QuickSort on Doubly Linked List kartik Follow Improve Article Tags : Linked List Sorting DSA Quick Sort Linked-List-Sorting +1 More Practice Tags : Linked ListSorting Similar Reads Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s 12 min read Time and Space Complexity Analysis of Quick Sort The time complexity of Quick Sort is O(n log n) on average case, but can become O(n^2) in the worst-case. The space complexity of Quick Sort in the best case is O(log n), while in the worst-case scenario, it becomes O(n) due to unbalanced partitioning causing a skewed recursion tree that requires a 4 min read Application and uses of Quicksort Quicksort: Quick sort is a Divide Conquer algorithm and the fastest sorting algorithm. In quick sort, it creates two empty arrays to hold elements less than the pivot element and the element greater than the pivot element and then recursively sort the sub-arrays. There are many versions of Quicksort 2 min read QuickSort using different languagesC++ Program for Quick SortQuick Sort is one of the most efficient sorting algorithms available to sort the given dataset. It is known for its efficiency in handling large datasets which made it a go-to choice for programmers looking to optimize their code.In C++, the STL's sort() function uses a mix of different sorting algo 4 min read Java Program for QuickSortLike Merge Sort, QuickSort is a Divide and Conquer algorithm. It picks an element as pivot and partitions the given array around the picked pivot. There are many different versions of QuickSort that pick pivot in different ways.Always pick first element as pivot.Always pick last element as pivot (im 2 min read QuickSort - PythonQuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array.How does QuickSort Algorithm work?QuickSort works on the principle of divide and c 4 min read p5.js | Quick SortQuickSort is a Divide and Conquer algorithm. It picks an element as pivot and partitions the given array around the picked pivot. There are many different versions of quickSort that pick pivot in different ways. Always pick first element as pivot. Always pick last element as pivot. Pick a random ele 3 min read Iterative QuickSortIterative Quick SortFollowing is a typical recursive implementation of Quick Sort that uses last element as pivot. C++// CPP code for recursive function of Quicksort #include <bits/stdc++.h> using namespace std; /* This function takes last element as pivot, places the pivot element at its correct position in sort 15+ min read C Program for Iterative Quick SortC // An iterative implementation of quick sort #include <stdio.h> // A utility function to swap two elements void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } /* This function is same in both iterative and recursive*/ int partition(int arr[], int l, int h) { int x = arr[h]; int i = (l 4 min read Java Program for Iterative Quick SortBelow is the implementation of Iterative Quick Sort:Java// Java implementation of iterative quick sort import java.io.*; public class IterativeQuickSort { void swap(int arr[], int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } /* This function is same in both iterative and recursive*/ in 3 min read Python Program for Iterative Quick SortThe code consists of two main functions: partition and quickSortIterative, along with a driver code to test the sorting process. The partition function is used for the process of partitioning a given subarray into two parts - elements less than or equal to the chosen pivot (arr[h]) on the left and e 4 min read Different implementations of QuickSortQuickSort using Random PivotingIn this article, we will discuss how to implement QuickSort using random pivoting. In QuickSort we first partition the array in place such that all elements to the left of the pivot element are smaller, while all elements to the right of the pivot are greater than the pivot. Then we recursively call 15+ min read QuickSort Tail Call Optimization (Reducing worst case space to Log n )Prerequisite : Tail Call EliminationIn QuickSort, partition function is in-place, but we need extra space for recursive function calls. A simple implementation of QuickSort makes two calls to itself and in worst case requires O(n) space on function call stack. The worst case happens when the selecte 11 min read Implement Quicksort with first element as pivotQuickSort is a Divide and Conquer algorithm. It picks an element as a pivot and partitions the given array around the pivot. There are many different versions of quickSort that pick the pivot in different ways. Always pick the first element as a pivot.Always pick the last element as a pivot.Pick a 13 min read Advanced Quick Sort (Hybrid Algorithm)Prerequisites: Insertion Sort, Quick Sort, Selection SortIn this article, a Hybrid algorithm with the combination of quick sort and insertion sort is implemented. As the name suggests, the Hybrid algorithm combines more than one algorithm. Why Hybrid algorithm: Quicksort algorithm is efficient if th 9 min read Quick Sort using Multi-threadingQuickSort is a popular sorting technique based on divide and conquer algorithm. In this technique, an element is chosen as a pivot and the array is partitioned around it. The target of partition is, given an array and an element x of the array as a pivot, put x at its correct position in a sorted ar 9 min read Stable QuickSortA sorting algorithm is said to be stable if it maintains the relative order of records in the case of equality of keys.Input : (1, 5), (3, 2) (1, 2) (5, 4) (6, 4) We need to sort key-value pairs in the increasing order of keys of first digit There are two possible solution for the two pairs where th 9 min read Dual pivot QuicksortAs we know, the single pivot quick sort takes a pivot from one of the ends of the array and partitioning the array, so that all elements are left to the pivot are less than or equal to the pivot, and all elements that are right to the pivot are greater than the pivot.The idea of dual pivot quick sor 10 min read 3-Way QuickSort (Dutch National Flag)In simple QuickSort algorithm, we select an element as pivot, partition the array around a pivot and recur for subarrays on the left and right of the pivot. Consider an array which has many redundant elements. For example, {1, 4, 2, 4, 2, 4, 1, 2, 4, 1, 2, 2, 2, 2, 4, 1, 4, 4, 4}. If 4 is picked as 15+ min read Visualization of QuickSortSorting Algorithm Visualization : Quick SortAn algorithm like Quicksort algorithm is hard to understand theoretically. We can understand easily by visualizing such kind of algorithms. In this article, a program that visualizes the Quicksort Algorithm has been implemented.The Graphical User Interface(GUI) is implemented in python using pygame 3 min read Visualizing Quick Sort using Tkinter in PythonPrerequisite: QuickSort Tkinter is a very easy-to-use and beginner-friendly GUI library that can be used to visualize the sorting algorithms. Here Quick Sort Algorithm is visualized which is a divide and conquer algorithm. It first considers a pivot element then, creates two subarrays to hold elemen 7 min read Visualization of Quick sort using MatplotlibVisualizing algorithms makes it easier to understand them by analyzing and comparing the number of operations that took place to compare and swap the elements. For this we will use matplotlib, to plot bar graphs to represent the elements of the array,  Approach : We will generate an array with rand 3 min read 3D Visualisation of Quick Sort using Matplotlib in PythonVisualizing algorithms makes it easier to understand them by analyzing and comparing the number of operations that took place to compare and swap the elements. 3D visualization of algorithms is less common, for this we will use Matplotlib to plot bar graphs and animate them to represent the elements 3 min read Partitions in QuickSortHoare's vs Lomuto partition scheme in QuickSortWe have discussed the implementation of QuickSort using Lomuto partition scheme. Lomuto's partition scheme is easy to implement as compared to Hoare scheme. This has inferior performance to Hoare's QuickSort.Lomuto's Partition Scheme:This algorithm works by assuming the pivot element as the last ele 15+ min read Quick Sort(Hoare's Partition) Visualization using JavaScriptGUI(Graphical User Interface) helps in better understanding than programs. In this article, we will visualize Quick Sort using JavaScript. We will see how the array is being partitioned into two parts and how we get the final sorted array. We will also visualize the time complexity of Quick Sort. Re 4 min read Quick Sort(Lomuto Partition) Visualization using JavaScriptGUI(Graphical User Interface) helps in better in understanding than programs. In this article, we will visualize Quick Sort using JavaScript. We will see how the array is being partitioned using Lomuto Partition and then how we get the final sorted array. We will also visualize the time complexity o 4 min read Implement Various Types of Partitions in Quick Sort in JavaQuicksort is a Divide and Conquer Algorithm that is used for sorting the elements. In this algorithm, we choose a pivot and partitions the given array according to the pivot. Quicksort algorithm is a mostly used algorithm because this algorithm is cache-friendly and performs in-place sorting of the 7 min read Some problems on QuickSortQuickSort on Singly Linked ListGiven 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: 5->4->1->3->2Output: 1->2->3->4->5Input: 4->3->2->1Output: 1->2->3->4Approach:The Quick Sort algorit 13 min read QuickSort on Doubly Linked ListGiven 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<->2Output: 1<->2<->3<->4<->5Explanation: Doubly Linked List after sorting using quicksort technique i 12 min read Nuts & Bolts Problem (Lock & Key problem) using Quick SortGiven a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping between nuts and bolts. Match nuts and bolts efficiently. Constraint: Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means a nut can only be compared with a bolt and a 12 min read Is Quick Sort Algorithm Adaptive or not Adaptive sorting algorithms are designed to take advantage of existing order in the input data. This means, if the array is already sorted or partially sorted, an adaptive algorithm will recognize that and sort the array faster than it would for a completely random array.Quick Sort is not an adaptiv 6 min read Like