package com.interview.linklist; /** * http://www.geeksforgeeks.org/quicksort-on-singly-linked-list/ * Test cases * 0 1 or more nodes * sorted reverse sorted nodes */ //keep head and tail of each result since caller function needs it to //set complete linklist. If we do not keep tail in each recursion we will //have to traverse to tail of left side which can be costly operation class HeadTail{ Node head; Node tail; } public class QuickSortSingleLinkList { public Node quickSort(Node head){ if(head == null || head.next == null){ return head; } Node smaller = null; Node larger = null; Node pivot = head; Node temp = head.next; pivot.next = null; LinkList ll = new LinkList(); while(temp != null){ Node next = temp.next; temp.next = null; if(temp.data < pivot.data){ smaller = ll.addAtFront(temp, smaller); }else{ larger = ll.addAtFront(temp, larger); } temp = next; } smaller = quickSort(smaller); larger = quickSort(larger); Node tail1 = smaller; //this is costly operation which can be prevented by keeping tail. while(tail1 != null && tail1.next != null){ tail1 = tail1.next; } if(smaller != null){ tail1.next = pivot; pivot.next = larger; return smaller; }else{ pivot.next = larger; return pivot; } } public Node quickSortFaster(Node head){ HeadTail result = quickSortUtil(head); return result.head; } /** * This version keeps tail of each recursion which helps us avoid going to tail in each recursion. * @param head * @return */ private HeadTail quickSortUtil(Node head){ if(head == null || head.next == null){ HeadTail headTail = new HeadTail(); headTail.head = head; headTail.tail = head; return headTail; } LinkList ll = new LinkList(); Node leftHead = null; Node rightHead = null; Node curr = head.next; head.next = null; Node next = null; while(curr != null){ next = curr.next; curr.next = null; if(curr.data < head.data){ leftHead = ll.addAtFront(curr, leftHead); }else{ rightHead = ll.addAtFront(curr, rightHead); } curr = next; } HeadTail leftSide = quickSortUtil(leftHead); HeadTail rightSide = quickSortUtil(rightHead); head.next= rightSide.head; HeadTail result = new HeadTail(); result.head = head; result.tail = head; if(leftSide.tail != null){ leftSide.tail.next = head; result.head = leftSide.head; } if(rightSide.head != null){ head.next = rightSide.head; result.tail = rightSide.tail; } return result; } public static void main(String args[]){ QuickSortSingleLinkList qss = new QuickSortSingleLinkList(); LinkList ll = new LinkList(); Node head = null; head = ll.addNode(11, head); head = ll.addNode(2, head); head = ll.addNode(-1, head); head = ll.addNode(50, head); head = ll.addNode(13, head); head = ll.addNode(-5, head); head = ll.addNode(10, head); head = ll.addNode(8, head); head = qss.quickSortFaster(head); ll.printList(head); } }