My algorithm for quickselect have to be faster than seq.sort + seq(k)
.
I think else if (low.length == 0) a(pivot)
is wrong and I think my algorithm is too slow for tests.
Some results for code:
Running performance tests on almost-sorted sequences
Test 1
quickSelect vs Arrays.sort: 0,0313 vs 0,0313
Test 2
quickSelect vs Arrays.sort: 0,0156 vs 0,0313
Test 3
quickSelect vs Arrays.sort: 0,0313 vs 0,0313
Test 4
quickSelect vs Arrays.sort: 0,0313 vs 0,0313
Test 5
quickSelect vs Arrays.sort: 0,0469 vs 0,0156
Testing quickSelect.find(List(1), 0)
Testing quickSelect.find(List(1, 1, 1, 1), 0)
Testing quickSelect.find(List(1, 1, 1, 1), 1)
Testing quickSelect.find(List(1, 1, 1, 1), 2)
Testing quickSelect.find(List(1, 1, 1, 1), 3)
Testing quickSelect.find(List(1, 2, 3), 0)
Testing quickSelect.find(List(1, 2, 3), 1)
- should compute correct results on some selected inputs *** FAILED ***
1 was not equal to 2
val rand = new scala.util.Random(21)
def find(seq: Seq[Int], k: Int): Int = {
require(0 <= k && k < seq.length)
val a: Array[Int] = seq.toArray[Int]
val pivot = rand.nextInt(a.length)
val (low, high) = a.partition(_ < a(pivot))
if (low.length == k-1) a(pivot)
else if (low.length == 0) a(pivot)
else if (low.length <= k) find(high, k - low.length)
else find(low, k)
}