I tried to search on Web and in my algorithms book
if the Lomuto's specific solution of QSort Partition is stable or not (I know that the Hoare's version is unstable)
but i didn't find a precise answer.
So I've tried to make same examples and it seems stable. But I didn't demonstrate it.
Could you help me?
If it is not stable, could you find me an example of input?
Lomuto's Partition Scheme: This algorithm works by assuming the pivot element as the last element. If any other element is given as a pivot element then swap it first with the last element.
Hoare partition is an algorithm that is used to partition an array about a pivot. All elements smaller than the pivot are on it's left (in any order) and all elements greater than the pivot are on it's right (in any order). Quicksort algorithm uses hoare paritition to partition the array.
Quicksort is a Divide and Conquer Algorithm that is used for sorting the elements. In this algorithm, we choose a pivot and partitions the given array according to the pivot.
I'm going to interpret "Quicksort with Lomuto's partition" as referring to the algorithm from here (slides 21–22).
This algorithm is unstable on the array [a, b, c] where c < a = b.
I found this counterexample by implementing the Quicksort algorithm in Python so that (like Python's built-in sort) it takes a key
function. By supplying an appropriate key function, I can make the sort think that certain elements are identical, but I can still distinguish them. Then it's just a matter of trying lots of permutations and spotting instability. The code below certainly doesn't exhaust the possible tests (one might want to try more than two identical elements, or multiple sets of identical elements), but it was good enough in this case.
def lomuto(A, key=lambda x:x):
def partition(A, p, r):
i = p - 1
pivot = A[r]
for j in range(p, r):
if key(A[j]) <= key(pivot):
i += 1
A[i], A[j] = A[j], A[i]
A[i+1], A[r] = A[r], A[i+1]
return i + 1
def quicksort(A, p, r):
if p < r:
q = partition(A, p, r)
quicksort(A, p, q-1)
quicksort(A, q+1, r)
quicksort(A, 0, len(A) - 1)
def test_stability(f, n):
"""Try to discover if the sorting function f is stable on n inputs;
printing the first counterexample found, if any."""
import itertools
for i in range(n - 1):
def order(P): return P.index((i, 0)) < P.index((i, 1))
array = [(j, 0) for j in range(n - 1)] + [(i, 1)]
for P in map(list, itertools.permutations(array)):
Q = P[:] # take a copy
f(Q, key=lambda x: x[0])
if order(P) != order(Q):
print(P, '->', Q)
return
>>> test_stability(lomuto, 3)
[(1, 0), (1, 1), (0, 0)] -> [(0, 0), (1, 1), (1, 0)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With