Skip to content

Instantly share code, notes, and snippets.

@sing1ee
Last active March 28, 2019 09:05
Show Gist options
  • Save sing1ee/5949395 to your computer and use it in GitHub Desktop.
Save sing1ee/5949395 to your computer and use it in GitHub Desktop.
QuickSort on Singly Linked List

###QuickSort on Singly Linked List

#####Rationale

  • 思路和数据的快速排序一样,都需要找到一个pivot元素、或者节点。然后将数组或者单向链表划分为两个部分,然后递归分别快排。
  • 针对数组进行快排的时候,交换交换不同位置的数值,在分而治之完成之后,数据就是排序好的。那么单向链表是什么样的情况呢?除了交换节点值之外,是否有其他更好的方法呢?可以修改指针,不进行数值交换。这可以获取更高的效率。
  • 在修改指针的过程中,会产生新的头指针以及尾指针,要记录下来。在partition之后,要将小于pivot的的部分、pivot、以及大于pivot的部分重新串起来成为一个singly linked list。

#####Choose pivot

  • choose the first node or the last node
  • choose a random node -> average: O(NlogN) worst: O(N^2) generate a random num less than the length of singly linked list, and choose that node as pivot
  • choose the median node -> worst: O(NlogN) Median of median selection algorithm to choose the median node.

####Implementation

    // choose the last node as the pivot
    public ListNode quickSortRecur(ListNode head, ListNode tail) {
        
    	if (head == tail) return head;
    	
    	ListNode pivot = tail, cur = head, pre = null, newhead = null;
    	
    	while(pivot != cur) {
    		if(cur.val < pivot.val) {
    			if (null == newhead) newhead = cur;
    			pre = cur;
    			cur = cur.next;
    		} else {
    			
    			tail.next = cur;
    			tail = tail.next;
    			ListNode tmp = cur.next;
    			cur.next = null;
    			cur = tmp;
    			if (null != pre) {
    				pre.next = cur;
    			}
    		}
    	}
    	if (pre != null) {
    		newhead = quickSortRecur(newhead, pre);
    		ListNode tmp = newhead;
    		while(pivot != tmp.next) tmp = tmp.next;
    		tmp.next = pivot;
    	}else {
    		newhead = pivot;
    	}
    	if (pivot != tail)
    		pivot.next = quickSortRecur(pivot.next, tail);
    	return newhead;
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment