If I were to sort the list of numbers 1,7,5,7,1 using Hoare's algorithm as described at the very beginning of wikipedia item on Hoare partition scheme with 5 being the pivot, and the indexes start at 1 and 1, then what would happen? If they are switched, nothing is really sorted. And the same goes for the two indexes both landing on numbers greater than the pivot, for example, 7 and 7. How would Hoare's algorithm handle such a case?
-
2Please improve the presentation of the list. Far as I remember, Hoare presented two variants of what was later to be called Hoare partition scheme (one titled "Partition without Exchange") in "the original article": please quote the algorithm you are referring to, or otherwise unambiguously identify it. – greybeard Feb 20 '18 at 23:03
-
@greybeard the original article is here (I was using the version first described, at the very beginning): https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme – PickleDonk Feb 20 '18 at 23:15
-
(I thought the 1961 presentation of ACM algorithms 63 & 64 pre-dated wikipedia as well as the article in The Computer Journal.) – greybeard Feb 20 '18 at 23:28
-
@greybeard from my understanding of quicksort from the wikipedia article, using the hoare method, you would have two indexes: i, at the first element in the array, and j, at the last element in the array. Then the elements at these indexes would be compared: if i is <= pivot and j >= pivot, the elements are swapped. Then, i is incremented, and j is decremented. The comparison happens again and again, until i and j cross each other. But if the elements they are switching are both less than the pivot, or both greater than the pivot, then what happens? – PickleDonk Feb 20 '18 at 23:42
-
One has to be careful to tell/keep element at index from index in comparisons: the first is used to control data movement, the latter for loop termination. – greybeard Feb 21 '18 at 00:24
-
See also: What if Elements Being Compared in Hoare's Quicksort Are the Same? – greybeard Feb 23 '18 at 07:32
-
See also: the Pedagogical Dimension, which warns us how tricky it is to implement Hoare's partition. – John L. Aug 22 '18 at 01:56
2 Answers
You've misunderstood the algorithm and it doesn't have the behaviour you suggest.
Let the pivot value be $p$. The algorithm searches from the left for a value $\ell\geq p$ and from the right for a value $r\leq p$. It then only swaps them if they're in the wrong order relative to each other, i.e., if $\ell>r$, so it will never exchange two identical array elements.
In your example, the algorithm would either swap the 1 on the left with the 7 on the right, or the 7 on the left with the 1 on the right, depending on exactly how it is implemented.

- 81,689
- 26
- 141
- 235
-
Not really. On https://cs.stackexchange.com/questions/92562/question-regarding-hoares-partitioning-scheme-and-a-slight-modification-to-it/93702#93702 I analyzed various variants of the partition algo. – Bulat Aug 20 '18 at 11:55
-
This answer contradicts the description of the algorithm at wikipedia item, which reads, "Hoare uses two indices that start at the ends of the array being partitioned, then move toward each other, until they detect an inversion: a pair of elements, one greater than or equal to the pivot, one lesser or equal, that are in the wrong order relative to each other. The inverted elements are then swapped" (bold font added by me). Note the "equal to" part in the description is critical in this question and all its answers. – John L. Aug 22 '18 at 01:39
-
Of course, this answer might be updated to claim that the algorithm can use extra steps to detect whether the elements encountered are equal (to the pivot value) and NOT exchange the two elements in those situations. However, we will then have, apparently, an uncommon version of the algorithm that is not the topic of this question. – John L. Aug 22 '18 at 01:48
-
If we just want to answer the specific question of OP, "What if ... both land on Values Less than Pivot?" (not on values equals to Pivot), then this answer may make more sense, since if the algorithm exchanges two equal elements, then both elements will must be equal to the Pivot. – John L. Aug 22 '18 at 02:04
-
@Apass.Jack OK, fixed. But neither the version I originally described nor the version in the Wikipedia article will ever swap identical elements so I'm not sure there was a huge issue. – David Richerby Aug 22 '18 at 15:03
-
The version in the Wikipedia does swap identical elements as I have verified by tracing an actual program. Have you done the same? You can also check, for example, a stackoverflow answer on why does Hoare partitioning work, where you can find the following. "Note that sometimes the i and j pointer will actually both stop on E values. When this happens, the values will be switched, even though there's no need for it." – John L. Aug 22 '18 at 15:24
-
According to @Bulat's careful analysis, in order to avoid endless loop, we do need to switch when both pointers stop on values equal to the pivot. – John L. Aug 22 '18 at 15:32
-
-
I am not sure what you imply by your last comment, "the Wikipedia article contradicts itself". Let me state the fact in a way that is independent of Wikipedia, as pointed out by @Bulat: the algorithm you stated does not work in some (corner) cases. – John L. Aug 28 '18 at 09:16
-
@Apass.Jack Wikipedia's description of the algorithm says that array elements are only swapped if they are in the wrong order, relative to one another; their pseudocode swaps them regardless. – David Richerby Aug 28 '18 at 10:11
-
@Apass.Jack David,yes - Wikipedia is incorrect saying that the algo always find an inversion. OTOH, this allows to simplify the description, focusing on the most important point of the algorithm at the first approach. So I'm not sure how it should be edited. Anyway, it should be obvious for you that wikipedia description and algo text contradict each other. – Bulat Aug 28 '18 at 13:47
Here is the pseudocode at wikipedia on quicksort using the Hoare partition scheme:
algorithm quicksort(A, lo, hi) is
if lo < hi then
p := partition(A, lo, hi)
quicksort(A, lo, p)
quicksort(A, p + 1, hi)
algorithm partition(A, lo, hi) is
pivot := A[lo]
i := lo - 1
j := hi + 1
loop forever
do i := i + 1 while A[i] < pivot
do j := j - 1 while A[j] > pivot
if i >= j then
return j
swap A[i] with A[j]
The indexes never start at the same number in partition
:
hi
is at least lo
+1 (j
is at least i+3
).
They start indexing "from the ends" to "meet in the middle".
Assuming the list a, g, e, g, a from the question, indexing starting at 1 and pivot
"magically" assuming e (the pseudo-code shown would set it to a), i
gets initialised to 0 and i
to 6 in the first execution of partition
.
The 1st "do - while" in the "forever-loop" would set i
to 1 unconditionally and to 2 because A[i]
, which is A[1]
, (a) is smaller than pivot
(e).
The 2nd "do - while" would stop right after setting j
to 5:
A[5]
already is smaller than pivot
.
i
is smaller than j
: partition
isn't done
i
and j
index a pair of elements in A
deserving a swap - guess what?
-
1PickleDonk, as everyone else, is invited to try and make this useful as can be. "Everyone" presenting an example with element values possibly confused with index values in an introductory context should be tarred and feathered. – greybeard Feb 21 '18 at 06:19