QuickSort on Singly Linked List

24 Jun, 2022
QuickSort on Doubly Linked List is discussed here. QuickSort on Singly linked list was given as an exercise. Following is C++ implementation for same. The important things about implementation are, it changes pointers rather swapping data and time complexity is same as the implementation for Doubly Linked List. 
In partition(), we consider last element as pivot. We traverse through the current list and if a node has value greater than pivot, we move it after tail. If the node has smaller value, we keep it at its current position. 
In QuickSortRecur(), we first call partition() which places pivot at correct position and returns pivot. After pivot is placed at correct position, we find tail node of left side (list before pivot) and recur for left list. Finally, we recur for right list.
Implementation”:
C++
Java
Python3
C#
Javascript
C
// C++ program for Quick Sort on Singly Linked List#include <cstdio>#include <iostream>using namespace std;  /* a node of the singly linked list */struct Node {    int data;    struct Node* next;};  /* A utility function to insert a node at the beginning of * linked list */void push(struct Node** head_ref, int new_data){    /* allocate node */    struct Node* new_node = new Node;      /* put in the data */    new_node->data = new_data;      /* link the old list off the new node */    new_node->next = (*head_ref);      /* move the head to point to the new node */    (*head_ref) = new_node;}  /* A utility function to print linked list */void printList(struct Node* node){    while (node != NULL) {        printf("%d ", node->data);        node = node->next;    }    printf("\n");}  // Returns the last node of the liststruct Node* getTail(struct Node* cur){    while (cur != NULL && cur->next != NULL)        cur = cur->next;    return cur;}  // Partitions the list taking the last element as the pivotstruct Node* partition(struct Node* head, struct Node* end,                       struct Node** newHead,                       struct Node** newEnd){    struct Node* pivot = end;    struct Node *prev = NULL, *cur = head, *tail = pivot;      // During partition, both the head and end of the list    // might change which is updated in the newHead and    // newEnd variables    while (cur != pivot) {        if (cur->data < pivot->data) {            // First node that has a value less than the            // pivot - becomes the new head            if ((*newHead) == NULL)                (*newHead) = cur;              prev = cur;            cur = cur->next;        }        else // If cur node is greater than pivot        {            // Move cur node to next of tail, and change            // tail            if (prev)                prev->next = cur->next;            struct Node* tmp = cur->next;            cur->next = NULL;            tail->next = cur;            tail = cur;            cur = tmp;        }    }      // If the pivot data is the smallest element in the    // current list, pivot becomes the head    if ((*newHead) == NULL)        (*newHead) = pivot;      // Update newEnd to the current last node    (*newEnd) = tail;      // Return the pivot node    return pivot;}  // here the sorting happens exclusive of the end nodestruct Node* quickSortRecur(struct Node* head,                            struct Node* end){    // base condition    if (!head || head == end)        return head;      Node *newHead = NULL, *newEnd = NULL;      // Partition the list, newHead and newEnd will be    // updated by the partition function    struct Node* pivot        = partition(head, end, &newHead, &newEnd);      // If pivot is the smallest element - no need to recur    // for the left part.    if (newHead != pivot) {        // Set the node before the pivot node as NULL        struct Node* tmp = newHead;        while (tmp->next != pivot)            tmp = tmp->next;        tmp->next = NULL;          // Recur for the list before pivot        newHead = quickSortRecur(newHead, tmp);          // Change next of last node of the left half to        // pivot        tmp = getTail(newHead);        tmp->next = pivot;    }      // Recur for the list after the pivot element    pivot->next = quickSortRecur(pivot->next, newEnd);      return newHead;}  // The main function for quick sort. This is a wrapper over// recursive function quickSortRecur()void quickSort(struct Node** headRef){    (*headRef)        = quickSortRecur(*headRef, getTail(*headRef));    return;}  // Driver codeint main(){    struct Node* a = NULL;    push(&a, 5);    push(&a, 20);    push(&a, 4);    push(&a, 3);    push(&a, 30);      cout << "Linked List before sorting \n";    printList(a);      quickSort(&a);      cout << "Linked List after sorting \n";    printList(a);      return 0;}
// Java program for Quick Sort on Singly Linked List  /*sort a linked list using quick sort*/publicclass QuickSortLinkedList {    static class Node {        int data;        Node next;          Node(int d)        {            this.data = d;            this.next = null;        }    }      Node head;      void addNode(int data)    {        if (head == null) {            head = new Node(data);            return;        }          Node curr = head;        while (curr.next != null)            curr = curr.next;          Node newNode = new Node(data);        curr.next = newNode;    }      void printList(Node n)    {        while (n != null) {            System.out.print(n.data);            System.out.print(" ");            n = n.next;        }    }      // takes first and last node,    // but do not break any links in    // the whole linked list    Node paritionLast(Node start, Node end)    {        if (start == end || start == null || end == null)            return start;          Node pivot_prev = start;        Node curr = start;        int pivot = end.data;          // iterate till one before the end,        // no need to iterate till the end        // because end is pivot        while (start != end) {            if (start.data < pivot) {                // keep tracks of last modified item                pivot_prev = curr;                int temp = curr.data;                curr.data = start.data;                start.data = temp;                curr = curr.next;            }            start = start.next;        }          // swap the position of curr i.e.        // next suitable index and pivot        int temp = curr.data;        curr.data = pivot;        end.data = temp;          // return one previous to current        // because current is now pointing to pivot        return pivot_prev;    }      void sort(Node start, Node end)    {        if(start == null || start == end|| start == end.next )            return;          // split list and partition recurse        Node pivot_prev = paritionLast(start, end);        sort(start, pivot_prev);          // if pivot is picked and moved to the start,        // that means start and pivot is same        // so pick from next of pivot        if (pivot_prev != null && pivot_prev == start)            sort(pivot_prev.next, end);          // if pivot is in between of the list,        // start from next of pivot,        // since we have pivot_prev, so we move two nodes        else if (pivot_prev != null                 && pivot_prev.next != null)            sort(pivot_prev.next.next, end);    }      // Driver Codepublic    static void main(String[] args)    {        QuickSortLinkedList list            = new QuickSortLinkedList();        list.addNode(30);        list.addNode(3);        list.addNode(4);        list.addNode(20);        list.addNode(5);          Node n = list.head;        while (n.next != null)            n = n.next;          System.out.println("Linked List before sorting");        list.printList(list.head);          list.sort(list.head, n);          System.out.println("\nLinked List after sorting");        list.printList(list.head);    }}  // This code is contributed by trinadumca
'''  sort a linked list using quick sort  '''  class Node:    def __init__(self, val):        self.data = val        self.next = None  class QuickSortLinkedList:      def __init__(self):        self.head=None      def addNode(self,data):        if (self.head == None):            self.head = Node(data)            return          curr = self.head        while (curr.next != None):            curr = curr.next          newNode = Node(data)        curr.next = newNode      def printList(self,n):        while (n != None):            print(n.data, end=" ")            n = n.next      ''' takes first and last node,but do not    break any links in    the whole linked list'''    def paritionLast(self,start, end):        if (start == end or start == None or end == None):            return start          pivot_prev = start        curr = start        pivot = end.data          '''iterate till one before the end,         no need to iterate till the end because end is pivot'''          while (start != end):            if (start.data < pivot):                                # keep tracks of last modified item                pivot_prev = curr                temp = curr.data                curr.data = start.data                start.data = temp                curr = curr.next            start = start.next          '''swap the position of curr i.e.         next suitable index and pivot'''          temp = curr.data        curr.data = pivot        end.data = temp          ''' return one previous to current because         current is now pointing to pivot '''        return pivot_prev      def sort(self, start, end):        if(start == None or start == end or start == end.next):            return          # split list and partition recurse        pivot_prev = self.paritionLast(start, end)        self.sort(start, pivot_prev)          '''        if pivot is picked and moved to the start,        that means start and pivot is same         so pick from next of pivot        '''        if(pivot_prev != None and pivot_prev == start):            self.sort(pivot_prev.next, end)          # if pivot is in between of the list,start from next of pivot,        # since we have pivot_prev, so we move two nodes        elif (pivot_prev != None and pivot_prev.next != None):            self.sort(pivot_prev.next.next, end)  if __name__ == "__main__":    ll = QuickSortLinkedList()    ll.addNode(30)    ll.addNode(3)    ll.addNode(4)    ll.addNode(20)    ll.addNode(5)      n = ll.head    while (n.next != None):        n = n.next      print("\nLinked List before sorting")    ll.printList(ll.head)      ll.sort(ll.head, n)      print("\nLinked List after sorting");    ll.printList(ll.head)          # This code is contributed by humpheykibet.
// C# program for Quick Sort on// Singly Linked Listusing System;  /*sort a linked list using quick sort*/class GFG {    public class Node {        public int data;        public Node next;          public Node(int d)        {            this.data = d;            this.next = null;        }    }      Node head;      void addNode(int data)    {        if (head == null) {            head = new Node(data);            return;        }          Node curr = head;        while (curr.next != null)            curr = curr.next;          Node newNode = new Node(data);        curr.next = newNode;    }      void printList(Node n)    {        while (n != null) {            Console.Write(n.data);            Console.Write(" ");            n = n.next;        }    }      // takes first and last node,    // but do not break any links in    // the whole linked list    Node paritionLast(Node start, Node end)    {        if (start == end || start == null || end == null)            return start;          Node pivot_prev = start;        Node curr = start;        int pivot = end.data;          // iterate till one before the end,        // no need to iterate till the end        // because end is pivot        int temp;        while (start != end) {              if (start.data < pivot) {                // keep tracks of last modified item                pivot_prev = curr;                temp = curr.data;                curr.data = start.data;                start.data = temp;                curr = curr.next;            }            start = start.next;        }          // swap the position of curr i.e.        // next suitable index and pivot        temp = curr.data;        curr.data = pivot;        end.data = temp;          // return one previous to current        // because current is now pointing to pivot        return pivot_prev;    }      void sort(Node start, Node end)    {        if (start == end)            return;          // split list and partition recurse        Node pivot_prev = paritionLast(start, end);        sort(start, pivot_prev);          // if pivot is picked and moved to the start,        // that means start and pivot is same        // so pick from next of pivot        if (pivot_prev != null && pivot_prev == start)            sort(pivot_prev.next, end);          // if pivot is in between of the list,        // start from next of pivot,        // since we have pivot_prev, so we move two nodes        else if (pivot_prev != null                 && pivot_prev.next != null)            sort(pivot_prev.next.next, end);    }      // Driver Code    public static void Main(String[] args)    {        GFG list = new GFG();        list.addNode(30);        list.addNode(3);        list.addNode(4);        list.addNode(20);        list.addNode(5);          Node n = list.head;        while (n.next != null)            n = n.next;          Console.WriteLine("Linked List before sorting");        list.printList(list.head);          list.sort(list.head, n);          Console.WriteLine("\nLinked List after sorting");        list.printList(list.head);    }}  // This code is contributed by 29AjayKumar
<script>// javascript program for Quick Sort on Singly Linked List  /*sort a linked list using quick sort*/       class Node {        constructor(val) {            this.data = val;            this.next = null;        }    }      var head;      function addNode(data) {        if (head == null) {            head = new Node(data);            return;        }          var curr = head;        while (curr.next != null)            curr = curr.next;          var newNode = new Node(data);        curr.next = newNode;    }      function printList( n) {        while (n != null) {            document.write(n.data);            document.write(" ");            n = n.next;        }    }      // takes first and last node,    // but do not break any links in    // the whole linked list    function paritionLast( start,  end) {        if (start == end || start == null || end == null)            return start;          var pivot_prev = start;        var curr = start;        var pivot = end.data;          // iterate till one before the end,        // no need to iterate till the end        // because end is pivot        while (start != end) {            if (start.data < pivot) {                // keep tracks of last modified item                pivot_prev = curr;                var temp = curr.data;                curr.data = start.data;                start.data = temp;                curr = curr.next;            }            start = start.next;        }          // swap the position of curr i.e.        // next suitable index and pivot        var temp = curr.data;        curr.data = pivot;        end.data = temp;          // return one previous to current        // because current is now pointing to pivot        return pivot_prev;    }      function sort( start,  end) {        if (start == null || start == end || start == end.next)            return;          // split list and partition recurse        var pivot_prev = paritionLast(start, end);        sort(start, pivot_prev);          // if pivot is picked and moved to the start,        // that means start and pivot is same        // so pick from next of pivot        if (pivot_prev != null && pivot_prev == start)            sort(pivot_prev.next, end);          // if pivot is in between of the list,        // start from next of pivot,        // since we have pivot_prev, so we move two nodes        else if (pivot_prev != null && pivot_prev.next != null)            sort(pivot_prev.next.next, end);    }      // Driver Code              addNode(30);        addNode(3);        addNode(4);        addNode(20);        addNode(5);          var n = head;        while (n.next != null)            n = n.next;          document.write("Linked List before sorting<br/>");        printList(head);          sort(head, n);          document.write("<br/>Linked List after sorting<br/>");        printList(head);  // This code contributed by umadevi9616 </script>
#include <stdio.h>#include <stdlib.h>  //Creating  structurestruct Node{    int data;    struct Node *next;};//Add new node at end of linked list void insert(struct Node **head, int value){    //Create dynamic node    struct Node *node = (struct Node *) malloc(sizeof(struct Node));    if (node == NULL)    {      //checking memory overflow        printf("Memory overflow\n");    }    else    {        node->data = value;        node->next = NULL;        if ( *head == NULL)        {            *head = node;        }        else        {            struct Node *temp = *head;            //finding last node            while (temp->next != NULL)            {                temp = temp->next;            }            //adding node at last possition            temp->next = node;        }    }}//Displaying linked list elementvoid display(struct Node *head){    if (head == NULL)    {        printf("Empty linked list");        return;    }    struct Node *temp = head;    printf("\n Linked List :");    while (temp != NULL)    {        printf("  %d", temp->data);        temp = temp->next;    }}//Finding last node of linked liststruct Node *last_node(struct Node *head){    struct Node *temp = head;    while (temp != NULL && temp->next != NULL)    {        temp = temp->next;    }    return temp;}//We are Setting the given last node position to its proper positionstruct Node *parition(struct Node *first, struct Node *last){    //Get first node of given linked list    struct Node *pivot = first;    struct Node *front = first;    int temp = 0;    while (front != NULL && front != last)    {        if (front->data < last->data)        {            pivot = first;            //Swapping  node values            temp = first->data;            first->data = front->data;            front->data = temp;            //Visiting the next node            first = first->next;        }        //Visiting the next node        front = front->next;    }    //Change last node value to current node    temp = first->data;    first->data = last->data;    last->data = temp;    return pivot;}//Performing quick sort in  the given linked listvoid quick_sort(struct Node *first, struct Node *last){    if (first == last)    {        return;    }    struct Node *pivot = parition(first, last);    if (pivot != NULL && pivot->next != NULL)    {        quick_sort(pivot->next, last);    }    if (pivot != NULL && first != pivot)    {        quick_sort(first, pivot);    }}int main(){    struct Node *head = NULL;    //Create linked list    insert( &head, 41);    insert( &head, 5);    insert( &head, 7);    insert( &head, 22);    insert( &head, 28);    insert( &head, 63);    insert( &head, 4);    insert( &head, 8);    insert( &head, 2);    insert( &head, 11);    printf("\n Before Sort ");    display(head);    quick_sort(head, last_node(head));    printf("\n After Sort ");    display(head);    return 0;}
Linked List before sorting 
30 3 4 20 5 
Linked List after sorting 
3 4 5 20 30 
Time Complexity: O(nlogn)  
It takes O(n^2) in worst case and O(nlogn) in average or best case.
Auxiliary Space: O(n)
As extra space is used in recursion call stack.
TrinaD
29AjayKumar
sudoaccessdenied
umadevi9616
humphreykibet
anikaseth98
kashishsoda
simranarora5sos
sayanc170
abhijeet19403
hardikkoriintern
Linked-List-Sorting
Quick Sort
Linked List
Sorting
Linked List
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
What is Data Structure: Types, Classifications and Applications
Linked List vs Array
Implementing a Linked List in Java using Class
Find Length of a Linked List (Iterative and Recursive)
Merge Sort
Bubble Sort Algorithm
QuickSort
Insertion Sort
Selection Sort Algorithm