Skip to main content
Minor clarification.
Source Link
John L.
  • 39.1k
  • 4
  • 34
  • 91

The simple implementation idea is to separate the values into three groups: values less than the pivot, values equal to the pivot, and values greater than the pivot.

In pseudocode, the algorithm looks like the following.

algorithm quicksort(A, lo, hi):
    if lo < hi then
        p := pivot(A, lo, hi)
        left, right := three-way-partition(A, p, lo, hi) 

        quicksort(A, lo, left - 1)
        quicksort(A, right, hi)

The partition procedure looks like the following.

procedure three-way-partition(A, pivot, lo, hi):
    l ← lo
    r ← lo
    u ← hi

    while r ≤ u:
        if A[r] < pivot:
            swap A[l] and A[r]
            l ← l + 1
            r ← r + 1
        else if A[r] > pivot:
            swap A[r] and A[u]
            u ← u - 1
        else: // the element is equal to pivot
            r ← r + 1
    return l, r

It uses three indices l, r and u (left, right, and upper bound), maintaining the following invariant in the while loop.

  • lo ≤ l ≤ r ≤ u ≤ hi
  • the elements with index in [lo, l) are smaller to the pivot.
  • the elements with index in [l, r) are equal to the pivot.
  • the elements with index in [r, u] are not examined yet.
  • the elements with index in (u, hi] are greater than the pivot.

There are a few minor variants. The above should be enough for you to understand what is going on.

The simple implementation idea is to separate the values into three groups: values less than the pivot, values equal to the pivot, and values greater than the pivot.

In pseudocode, the algorithm looks like the following.

algorithm quicksort(A, lo, hi):
    if lo < hi then
        p := pivot(A, lo, hi)
        left, right := three-way-partition(A, p, lo, hi) 

        quicksort(A, lo, left - 1)
        quicksort(A, right, hi)

The partition procedure looks like the following.

procedure three-way-partition(A, pivot, lo, hi):
    l ← lo
    r ← lo
    u ← hi

    while r ≤ u:
        if A[r] < pivot:
            swap A[l] and A[r]
            l ← l + 1
            r ← r + 1
        else if A[r] > pivot:
            swap A[r] and A[u]
            u ← u - 1
        else: // the element is equal to pivot
            r ← r + 1
    return l, r

It uses three indices l, r and u (left, right, and upper bound), maintaining the following invariant in the while loop.

  • lo ≤ l ≤ r ≤ u ≤ hi
  • the elements with index in [lo, l) are smaller to the pivot.
  • the elements with index in [l, r) are equal to the pivot.
  • the elements with index in [r, u] are not examined yet.
  • the elements with index in (u, hi] are greater than the pivot.

The simple implementation idea is to separate the values into three groups: values less than the pivot, values equal to the pivot, and values greater than the pivot.

In pseudocode, the algorithm looks like the following.

algorithm quicksort(A, lo, hi):
    if lo < hi then
        p  pivot(A, lo, hi)
        left, right  three-way-partition(A, p, lo, hi) 

        quicksort(A, lo, left - 1)
        quicksort(A, right, hi)

The partition procedure looks like the following.

procedure three-way-partition(A, pivot, lo, hi):
    l ← lo
    r ← lo
    u ← hi

    while r ≤ u:
        if A[r] < pivot:
            swap A[l] and A[r]
            l ← l + 1
            r ← r + 1
        else if A[r] > pivot:
            swap A[r] and A[u]
            u ← u - 1
        else: // the element is equal to pivot
            r ← r + 1
    return l, r

It uses three indices l, r and u (left, right, and upper bound), maintaining the following invariant in the while loop.

  • lo ≤ l ≤ r ≤ u ≤ hi
  • the elements with index in [lo, l) are smaller to the pivot.
  • the elements with index in [l, r) are equal to the pivot.
  • the elements with index in [r, u] are not examined yet.
  • the elements with index in (u, hi] are greater than the pivot.

There are a few minor variants. The above should be enough for you to understand what is going on.

Source Link
John L.
  • 39.1k
  • 4
  • 34
  • 91

The simple implementation idea is to separate the values into three groups: values less than the pivot, values equal to the pivot, and values greater than the pivot.

In pseudocode, the algorithm looks like the following.

algorithm quicksort(A, lo, hi):
    if lo < hi then
        p := pivot(A, lo, hi)
        left, right := three-way-partition(A, p, lo, hi) 

        quicksort(A, lo, left - 1)
        quicksort(A, right, hi)

The partition procedure looks like the following.

procedure three-way-partition(A, pivot, lo, hi):
    l ← lo
    r ← lo
    u ← hi

    while r ≤ u:
        if A[r] < pivot:
            swap A[l] and A[r]
            l ← l + 1
            r ← r + 1
        else if A[r] > pivot:
            swap A[r] and A[u]
            u ← u - 1
        else: // the element is equal to pivot
            r ← r + 1
    return l, r

It uses three indices l, r and u (left, right, and upper bound), maintaining the following invariant in the while loop.

  • lo ≤ l ≤ r ≤ u ≤ hi
  • the elements with index in [lo, l) are smaller to the pivot.
  • the elements with index in [l, r) are equal to the pivot.
  • the elements with index in [r, u] are not examined yet.
  • the elements with index in (u, hi] are greater than the pivot.