Randomized Sort
Updated:
⚠️ This post was created when I was in high school and is no longer maintained.
1. Intuition
Instead of always using
A(r)
as the pivot, we will select a randomly chosen element from the subarrayA(p, r)
We do so by first exchanging elementA(r)
with an element chosen at random fromA(p, r)
. By randomly sampling the range p…r, we ensure that the pivot elementx = A[r]
is equally likely to be any of the(r-p+1)
elements in the subarray.
Because we randomly choose the pivot element, we expect the split of the input array to be reasonably well balanced on average
2. Pseudocode
algorithm RandomQuickSort(array, start, end):
if start < end then
pivot_i = RandomPartition(array, start, end)
QuickSort(array, start, pivot_i-1)
QuickSort(array, pivot_i+1, end)
function RandomPartition(array, start, end):
rand_i = Random(p, r)
exchange A[r] with A[rand_i]
return Partition(array, start, end)
function Partition(array, start, end):
pivot = array[end]
i = start - 1
For j = start to end-1 do
if array[j] <= pivot then
i += 1
exchange array[i] with array[j]
exchange array[end] with array[i+1]
return i+1
3. Code
// Scala
class QuickSort() {
protected var _array: Array[Double] = _
def this(array: Array[Double]) {
this()
println(">> QuickSort Constructor called")
this._array = array
}
def quickSort(start: Int, end: Int): Unit = {
if (start < end) {
var pivot_i = partition( start, end)
quickSort(start, pivot_i-1)
quickSort(pivot_i+1, end)
}
}
protected def partition(start: Int, end: Int): Int = {
var pivot = _array(end)
var i = start - 1
for (j <- start until end) {
if (_array(j) < pivot) {
i += 1
// swap
var tmp = _array(i)
_array(i) = _array(j)
_array(j) = tmp
}
}
var tmp = _array(i+1)
_array(i+1) = _array(end)
_array(end) = tmp
return i+1
}
def printArray {
println(_array.deep.mkString(" "))
}
}
class RandomQuickSort(val array: Array[Double]) extends QuickSort(array) {
println("\nBefore sorting:")
println(array.deep.mkString(" "))
def randomPartition(start: Int, end: Int): Int = {
val rand_tmp = new scala.util.Random
val rand_i = start + rand_tmp.nextInt((end - start) + 1)
var tmp = _array(rand_i)
_array(rand_i) = _array(end)
_array(end) = tmp
return partition(start, end)
}
override def quickSort(start: Int, end: Int): Unit = {
if (start < end) {
var pivot_i = randomPartition(start, end)
quickSort(start, pivot_i-1)
quickSort(pivot_i+1, end)
}
}
}
object RandomQuickSortAlgo {
def main(args: Array[String]): Unit = {
val array = Array(4234,234234,23,234,-134,4123,41,578,-342,55,0.2323,0.325)
val randomQuickSort = new RandomQuickSort(array)
randomQuickSort.quickSort(0, array.length-1)
println("\nAfter sorting:")
randomQuickSort.printArray
}
}
# Python
import random
def random_partition(array, start, end):
rand_i = random.randint(start, end)
array[rand_i], array[end] = array[end], array[rand_i]
return partition(array, start, end)
def partition(array, start, end):
pivot = array[end]
i = start - 1
for j in range(start, end):
if array[j] <= pivot:
i += 1
array[i], array[j] = array[j], array[i]
array[end], array[i+1] = array[i+1], array[end]
return i+1
def random_quick_sort(array, start, end):
if start < end:
pivot_i = random_partition(array, start, end)
random_quick_sort(array, start, pivot_i-1)
random_quick_sort(array, pivot_i+1, end)
if __name__ == "__main__":
array = [4234,234234,23,234,-134,123,41,578,-342,55,0.9323,0.325]
# array = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print("Before sorting: ", array)
random_quick_sort(array, 0, len(array)-1)
print("After sorting: ", array)
Leave a comment