Quicksort

Posted by VitoDH Blog on December 22, 2019

Chapter 4 - Sorting and Searching - 2 - Quicksort: Sorting by Randomization

Source: Algorithm Design Manual(Skiena)

1. Definition

  • Select a random item p from the n items we seek to sort. Separate the n-1 other items into two piles
  • A low pile with all the elements that appear before p in sorted order
  • A high pile with all the elements taht appear after p in sorted order

2. Advantages

  • The pivot element p ends up in the exact array position it will reside in the final sorted order
  • After partitioning, no element flops to the other side in the final sorted order

3. Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def quicksort(s,low,high):
    p = None # index of partitioning
    
    if (high - low) > 0:
        p = partition(s,low,high)
        quicksort(s,low,p-1)
        quicksort(s,p+1,high)

def partition(s,low,high):
    p = high # select the last element to be the pivot
    firsthigh = low
    for i in range(low,high):
        if s[i] < s[p]:
            # swap the element between firsthigh and i
            # to make sure that elements left to the firsthigh is smaller than pivot
            s[i],s[firsthigh] = s[firsthigh],s[i]
            firsthigh += 1
   # move the pivot to the firsthigh position
   s[p],s[firsthigh] = s[firsthigh],s[p]
   return firsthigh

Complexity

  • The partitioning step consists of at most n swaps
  • Quicksort build a recursion tree of nested subranges of the n-element array
  • Runtime: O(nh) where h is the height of the recursion tree
    • Lucky case: Repeatedly pick the median element as the pivot: h=logn
    • Unlucky case: The pivot always splits the array as unequally as possible, i.e., the pivot is always the biggest or the smallest element in the subarray: h=n
  • Expected time: $\Theta(nlogn)$
    • good enough points: n/4 to 3/4n, height of good enough points $h_g=log_{\frac{4}{3}}n$
    • $h\approx 2h_g$

4. Randomized Algorithm

  • Add an initial step to the algorithm
    • We randomly permute the order of the n elements before we try to sort them, which takes O(n) time
    • Provide the guarantee that we can expect $\Theta(nlogn)$ running time whatever the initial input is
  • Randomization
    • Improve algorithms with bad worst-case but good average-case complexity
    • Make algorithms more robust to boundary cases and more efficient on highly structured input instances that confound heuristic decisions

5. Notes

  • Is Quicksort really quick?
    • The experiments shows that the quicksort is typically 2-3 times faster than mergesort or heapsort
    • The primary reason is that the operations in the innermost loop are simpler