As per the pseudo-code given in many websites, I have written this Hoare partitioning algorithm, which takes an array, the start and end indexes of the sub-array to be partitioned based on the pivot given. It works fine, but can somebody explain the logic, how it does what it does? Here’ the code:
def hoare(arr,start,end):
pivot = 4
i,j = start,end
while i < j:
while i < j and arr[i] <= pivot:
i += 1
while j >= i and arr[j] > pivot:
j -= 1
if i < j:
arr[i],arr[j] = arr[j],arr[i]
return j
There’s another variant of the partitioning, the Lomuto algorithm. It does something similar, although since I don’t understand the Hoare algorithm in the first place, I can’t spot the difference. Can anybody explain what’s going on in the algorithm, and which one gives a better performance in which case?
I’d suggest simulating this using a deck of cards and two pawns / coins to represent
iandj. Basically, the algorithm accomplishes these two things, simultaneously:iandjmeeting in the “middle” of the partition.This means that at any time,
iis either at the middle or left of it. The converse is true forj. Knowing this, one can see that what thewhileloops do is find an element that’s to the left of the middle but should be on the right, and vice versa. That is, find two elements that are in the wrong half. These are then swapped.When
iandjmeet in the middle, to the left you have either elements that were skipped by thewhile, because they’re smaller thanpivot; or elements that were swapped from the other side, and are thus also smaller thanpivot. (Vice versa for the elements right of the middle.)A possible source of confusion is that a zero-based array index can be thought to either point at an element, or to point between two elements. E.g. the index
0basically means “between the ‘zeroth’ and the first element in the array”, and when you’re accessing an element, you take the one following this position – makingarray[0]result in what’s intuitively the first element of the array.