public class Select {
public static void main(String[] args){
int length = 37; int rank = 10;
int[] data = new int[length];
Random rm = new Random();
for (int i = 0; i < length; i++) {
data[i] = rm.nextInt(100);
}
Select select = new Select();
System.out.println(Arrays.toString(data));
System.out.println(select.select(data, 0, length-1, rank));
Arrays.sort(data);
System.out.println(Arrays.toString(data));
}
private int select(int[] data,int low, int high, int rank){
if ((high-low)<5) {
insertSort(data, low, high);
return data[low+rank-1];
}
int group = (high - low + 5) / 5;
for (int i = 0; i < group; i++) {
int left = low + i*5;
int right = (low + i*5 + 4) > high ? high : (low + i*5 + 4);
int mid = (left + right) / 2;
insertSort(data, left, right);
swap(data, low+i, mid);
}
int pivot = select(data, low, low+group-1, (group+1)/2);
int threshold = partition(data, low, high, pivot);
int k = threshold - low + 1;
if (k == rank) {
return data[threshold];
}else if (k > rank) {
return select(data, low, threshold-1, rank);
}else {
return select(data, threshold+1, high, rank-k);
}
}
public int partition(int[] data, int low, int high, int pivot){
int index = 0;
for (int i = low; i <= high; i++) {
if (data[i] == pivot) {
index = i;
break;
}
}
swap(data, index, high);
int init = low - 1;
for (int i = low; i < high; i++) {
if (data[i] < pivot) {
init++;
swap(data, init, i);
}
}
swap(data, init+1, high);
return init+1;
}
private void swap(int[] data, int a, int b){
int temp = data[a];
data[a] = data[b];
data[b] = temp;
}
public void insertSort(int[] data,int low,int high){
for (int i = low+1; i <= high; i++) {
int key = data[i];
int k = i - 1;
while (k >= low && data[k] > key) {
data[k+1] = data[k];
k--;
}
data[k+1] = key;
}
}
}