0

I'm having trouble defining and proving a loop invariant for some implementation of Quicksort algorithm. This is neither Lomuto's nor Hoare's partition version.

If you know about some known version of Quicksort that is implemented this way, let me know, please.

Algorithm's implementation in Python:

def partition(arr: list, p: int, r: int):
    y = arr[p]
    i = p
    j = r + 1

    while i < j:
        i = i + 1

        while i <= r and A[i] < y:
            i = i + 1

        j = j - 1

        while j >= p and A[j] > y:
            j = j - 1

        if i <= j:
            swap(arr, i, j)

    swap(arr, j, p)

    return j


def quicksort(arr: list, p: int, r: int):
    if p < r:
        q = partition(arr, p, r)
        quicksort(arr, p, q - 1)
        quicksort(arr, q + 1, r)


def swap(arr: list, i, j):
    tmp = arr[i]
    arr[i] = arr[j]
    arr[j] = tmp

I have managed to define the following loop invariant (it might be incorrect):

At the beginning of each iteration of the while loop, for each index k in array A:

  • if k = p, so A[k] = y

  • if p < k <= i, so A[k] < y

  • if j <= k <= r, so A[k] > y

Please help me to define a loop invariant for the while loop in partition() method (if the above is incorrect), and prove it.

Dennis
  • 2,271
  • 6
  • 26
  • 42
  • that's a variation of quicksort known as Dutch-flag partitioning, it is used when array consists primarily of duplicates. instead of moving a single iterator forward, you move two iterators from start and end towards each other. they stop whenever they point at the same value (i.e. pivot) – mangusta Mar 30 '19 at 10:00
  • @mangusta I read about Dutch-flag partitioning, but it seems a bit different. In my case the pivot element is the first one (`y = arr[p]`). – Dennis Mar 30 '19 at 10:18
  • any element of array can be a pivot – mangusta Mar 30 '19 at 10:54
  • @mangusta: actually, any value can be a pivot, provided that array contains at least one element not larger and one not smaller. For instance, the mean could do. –  Mar 30 '19 at 17:41

1 Answers1

0

The invariant of the outer while expresses that among the sections of the array that have been scanned so far, namely the ranges A[p..i] and A[j..r], the left elements are not larger than the pivot and the right elements not smaller. (And of course, the content of A is a permutation of the initial content.)

When the loop exits, all left elements are not larger than all right elements, so that A[p..r] is partitioned.