Have been bashing my head in trying to debug my quicksort implementation and could use a new set of eyes. I'm following along Robert Sedgewick's Coursera Algorithms course and I have absolutely no idea what's wrong with the way I'm doing it (looks nearly identical to his java implementation). Any ideas? I know my partition method works since I've extensively stress-tested it (i.e if I submit low to be 0 and high as 2, then the array will be properly partitioned between those indices).
Also, I'm using quicksort as an in-place sort so that's why I'm not creating an auxiliary array.
def shuffle(arr)
arr.each_index do |i|
r = rand(0..i)
arr[i], arr[r] = arr[r], arr[i]
end
arr
end
def partition!(arr,low, high)
#debugger
arr = shuffle(arr)
i = low + 1
j = high
while true
until arr[i] >= arr[low]
break if i >= high
i+=1
end
until arr[j] <= arr[low]
j-=1
end
if i>=j
#done
arr[j], arr[low] = arr[low], arr[j]
break
else
#swap and continue
arr[i], arr[j] = arr[j], arr[i]
end
end
end
def quicksort(arr, low = 0, high=arr.length-1)
arr = shuffle(arr)
quicksort!(arr, low, high)
end
def quicksort!(arr, low, high)
#p "Quicksorting on low index #{low} and high index #{high}"
return arr if (high <= low)
j = partition!(arr, low, high)
quicksort!(arr, low, j-1)
quicksort!(arr, j+1, high)
end
You were almost there.
partition
should return j
. See the corresponding java code.
You already shuffle the array in quicksort
, no need to shuffle it again and again in partition
!
Also, note that your shuffle
method shuffles the whole array, independently from j
, low
and high
.
Shuffling only the left and right subarrays separately at each iteration would work, even though it would be unneeded.
quicksort
should return arr
.
def shuffle(arr)
arr.each_index do |i|
r = rand(0..i)
arr[i], arr[r] = arr[r], arr[i]
end
arr
end
def partition!(arr,low, high)
i = low + 1
j = high
while true
until arr[i] >= arr[low]
break if i >= high
i+=1
end
until arr[j] <= arr[low]
j-=1
end
if i>=j
#done
arr[j], arr[low] = arr[low], arr[j]
break
else
#swap and continue
arr[i], arr[j] = arr[j], arr[i]
end
end
j
end
def quicksort(arr, low = 0, high=arr.length-1)
arr = shuffle(arr)
quicksort!(arr, low, high)
arr
end
def quicksort!(arr, low, high)
return arr if (high <= low)
j = partition!(arr, low, high)
quicksort!(arr, low, j-1)
quicksort!(arr, j+1, high)
end
arr = [3,2,1,4,5]
p quicksort(arr)
# => [1, 2, 3, 4, 5]