Table of Contents
Given a linked list, we will sort the linked list using quick sort.
Example
Linked List before sorting
23 ->1 ->50 ->15 ->16 ->6
Linked List after sorting
1 ->6 ->15 ->16 ->23 ->50
Time Complexity : O()
In this method the main idea is to swap pointers rather than swaping data
Algorithm
Partition Algorithm
1. Take rightmost element as the pivot
Traverse through the list
a. If the node has value greater than pivot, we will move it after tail
b. else, keep it in same position
QuickSort Algorithm
1. Call Partition(), which places pivot at right position and returns the pivot
2. Find the tail node of the left sublist ie, left side of the pivot and recur for left list
3. Now, recur for right list
C++ Program
#include <iostream> #include <cstdio> using namespace std; // a node of the singly linked list // struct LLNode { int data; LLNode *next; }; //utility function to insert a LLNode at the beginning of linked list // void insertAtBeginning(LLNode**head,int dataToBeInserted) { LLNode*curr=new LLNode; //make a new LLNode with this data and next pointing to NULL curr->data=dataToBeInserted; curr->next=NULL; if(*head==NULL) //if list is empty then set the current formed LLNode as head of list *head=curr; else //make the next of the current LLNode point to the present head and make the current LLNode as the new head { curr->next=*head; *head=curr; } //O(1) constant time } // A utility function to print linked list // void display(LLNode**head) { LLNode*temp=*head; while(temp!=NULL) //till the list ends (NULL marks ending of list) { if(temp->next!=NULL) cout<<temp->data<<" ->"; else cout<<temp->data; temp=temp->next; //move to next node } //O(number of nodes) cout<<endl; } // Returns the last node of the list LLNode *getTail(LLNode *cur) { while (cur != NULL && cur->next != NULL) cur = cur->next; return cur; } // Partitions the list taking the last element as the pivot LLNode *partition(LLNode *head, LLNode *end, LLNode **newHead, LLNode **newEnd) { LLNode *pivot = end; LLNode *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 LLNode is greater than pivot { // Move cur LLNode to next of tail, and change tail if (prev) prev->next = cur->next; LLNode *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 LLNode return pivot; } //here the sorting happens exclusive of the end node LLNode *quickSortRecur(LLNode *head, LLNode *end) { // base condition if (!head || head == end) return head; LLNode *newHead = NULL, *newEnd = NULL; // Partition the list, newHead and newEnd will be updated // by the partition function LLNode *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 LLNode before the pivot LLNode as NULL LLNode *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 LLNode 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(LLNode **headRef) { (*headRef) = quickSortRecur(*headRef, getTail(*headRef)); return; } // Driver program to test above functions int main() { LLNode *head = NULL; LLNode *tail = NULL; insertAtBeginning(&head, 6); insertAtBeginning(&head, 16); insertAtBeginning(&head, 15); insertAtBeginning(&head, 50); insertAtBeginning(&head, 1); insertAtBeginning(&head, 23); cout << "Linked List before sorting \n"; display(&head); quickSort(&head); cout << "Linked List after sorting \n"; display(&head); return 0; }