设有一组N个数的数组, 我们要确定其中第k个最大者;
以下提供两种比较简单的算法:
- 冒泡排序: 把所有元素排序;然后取第k个;
- 先把前k个元素读入一个新数组; 然后进行从大到小的排序; 然后将之后元素依次读入,和第k个元素进行比较,小于第k个元素的忽略, 如果大于k个预算,则插入到其中正确位置,将最后一个挤掉;
import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
/**
* 选择问题;
*/
public class _01_01_p14 {
private final int LENGTH = 100000;
private final int K = 5000;
@Test
public void runTest() {
int[] intArr = new int[LENGTH];
Random random = new Random();
//生成随机数;
for (int i=0; i<=LENGTH-1; i++){
intArr[i] = random.nextInt(10000);
}
int[] intArr2 = Arrays.copyOf(intArr, LENGTH);
long start = System.currentTimeMillis();
bubleSort(intArr);
long end = System.currentTimeMillis();
System.out.println("数组中第" + K +"大的数为:" +intArr[K-1]);
System.out.println("查找用时为:" + (end - start) +"ms"); //12151
long start2 = System.currentTimeMillis();
int k = choiceSort(intArr2);
long end2 = System.currentTimeMillis();
System.out.println("数组中第" + K +"大的数为:" +k);
System.out.println("查找用时为:" + (end2 - start2) +"ms"); //88
}
/**
* 冒泡排序法
*/
public int[] bubleSort(int[] intArr){
int length = intArr.length;
for (int i=0; i<length; i++){
for (int j=i+1; j<length; j++){
if (intArr[j] > intArr[i]){
int temp = intArr[j];
intArr[j] = intArr[i];
intArr[i] = temp;
}
}
}
return intArr;
}
/**
* 选择排序法;
*/
public int choiceSort(int[] intArr){
int[] subArr = new int[K];
subArr = Arrays.copyOf(intArr, K);
subArr = bubleSort(subArr); //对subArr从大到小进行排序;
for (int i=K; i<LENGTH; i++){
//判断k之后的数据,是否大于subArr[K-1];
if (intArr[i] <= subArr[K-1]) {
continue;
} else {
//插入合适的位置;
insertData(subArr, intArr[i]);
}
}
return subArr[K-1];
}
/**
* 将数字插入有序数组
* @param arr
* @param num
*/
public void insertData(int[] arr, int num){
int length = arr.length;
int index = length - 1; //待插入位置
for (int i=0; i<length; i++){
if (num > arr[i]){
index = i;
break;
}
}
//index之后的元素后移;
for (int j=length-1; j>index; j--){
arr[j] = arr[j - 1];
}
arr[index] = num;
}
}