Randomized Sort
Created:
⚠️ 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 pick a random element from the subarrayA(p, r). We do so by first swappingA(r)with an element chosen at random fromA(p, r). By sampling the rangep...r, the pivotx = A[r]is equally likely to be any of the(r-p+1)elements.
Because the pivot is random, we expect the input array to split reasonably evenly 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