85 lines
1.9 KiB
Java
85 lines
1.9 KiB
Java
package presenter.algorithms.util;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Random;
|
|
|
|
/**
|
|
* Created by armin on 29.06.17.
|
|
*/
|
|
public class FastElementSelector {
|
|
|
|
/**
|
|
* @param a
|
|
* @param i
|
|
* @return
|
|
*/
|
|
public static Double randomizedSelect(ArrayList<Double> a, double i) {
|
|
int start = 0;
|
|
int end = a.size() - 1;
|
|
|
|
if (i >= end + 1) {
|
|
return a.get(end);
|
|
}
|
|
|
|
while (true) {
|
|
if (start >= end) {
|
|
return a.get(start);
|
|
}
|
|
int q = randomizedPartition(a, start, end);
|
|
int k = q - start + 1;
|
|
|
|
if (i == k) {
|
|
return a.get(q);
|
|
} else {
|
|
if (i < k) {
|
|
end = q - 1;
|
|
} else {
|
|
start = q + 1;
|
|
i = i - k;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param a
|
|
* @param start
|
|
* @param end
|
|
* @return
|
|
*/
|
|
private static int randomizedPartition(ArrayList<Double> a, int start, int end) {
|
|
int i = 0;
|
|
Random random = new Random(System.currentTimeMillis());
|
|
|
|
//alternative: ThreadLocalRandom.current()
|
|
if (start < end) {
|
|
i = start + random.nextInt(end - start);
|
|
} else {
|
|
i = end + random.nextInt(start - end);
|
|
}
|
|
|
|
Collections.swap(a, end, i);
|
|
return partition(a, start, end);
|
|
}
|
|
|
|
/**
|
|
* @param a
|
|
* @param start
|
|
* @param end
|
|
* @return
|
|
*/
|
|
private static int partition(ArrayList<Double> a, int start, int end) {
|
|
Double x = a.get(end);
|
|
int i = start - 1;
|
|
for (int j = start; j <= end - 1; j++) {
|
|
if (a.get(j) <= x) {
|
|
i++;
|
|
Collections.swap(a, i, j);
|
|
}
|
|
}
|
|
Collections.swap(a, i + 1, end);
|
|
return i + 1;
|
|
}
|
|
}
|