设有一组 N 个数而要确定其中第 K 个最大者,我们称之为选择问题(selection problem)。
该问题的一种解法就是将这 N 个数读进一个数组中,再通过某种简单的算法,比如冒泡排序法,以递减顺序将数组排序,然后返回位置 K 上的元素。
稍微好一点的算法可以先把前 K 个元素读入数组并(以递减的顺序)对其排序。接着,将剩下的元素再逐个读入。当新元素被读到时,如果它小于数组中的第 K 个元素则忽略之,否则就将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组。当算法终止时,位于第 K 个位置上的元素作为答案返回。
1 package c1.kmax; 2 3 import java.util.Arrays; 4 5 /** 6 * 一组 N 个数确定其中第 K 个最大者 7 * 8 * @author MicroCat 9 * 10 */ 11 public class KMax { 12 13 public static void main(String[] args) { 14 try { 15 int[] arr = { 12, 4, 6, 3, 4, 5, 0, -8 }; 16 int[] arr2 = { 12, 4, 6, 3, 4, 5, 0, -8 }; 17 int k = 5; 18 System.out.println("The " + k + " largest in arrays : " + kmax1(arr, k)); 19 System.out.println("The " + k + " largest in arrays : " + kmax2(arr2, k)); 20 } catch (Exception e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 } 25 26 /** 27 * 读入 K 个元素至新数组,以递减方式储存。 将剩下的元素再逐个读入。若小于新数组的最小值,跳过;否则,替换新数组最末位元素,重新排序。 28 * 最后返回新数组最末位元素。 29 * 30 * @param arr 31 * @param k 32 * @return 33 * @throws Exception 34 */ 35 public static int kmax2(int[] arr, int k) throws Exception { 36 try { 37 if (k <= 0 || k > arr.length) { 38 throw new Exception("k value out of range!"); 39 } 40 int[] karr = new int[k]; 41 System.arraycopy(arr, 0, karr, 0, k); 42 BubbleMaxToMin(karr); 43 for (int i = k; i < arr.length; i++) { 44 if (arr[i] <= karr[k - 1]) { 45 // print 46 System.out.println("circle" + (i - k + 1) + " : " + Arrays.toString(karr)); 47 continue; 48 } else { 49 karr[k - 1] = arr[i]; 50 BubbleMaxToMin(karr); 51 // print 52 System.out.println("circle" + (i - k + 1) + " : " + Arrays.toString(karr)); 53 } 54 } 55 System.out.println(Arrays.toString(karr)); 56 return karr[k - 1]; 57 } catch (Exception e) { 58 // TODO: handle exception 59 throw e; 60 } 61 } 62 63 /** 64 * 冒泡法由大到小排序 65 * 66 * @param karr 67 */ 68 private static void BubbleMaxToMin(int[] karr) { 69 for (int i = 0; i < karr.length; i++) { 70 for (int j = karr.length - 1; j > i; j--) { 71 if (karr[j] > karr[j - 1]) { 72 karr[j] = karr[j] ^ karr[j - 1]; 73 karr[j - 1] = karr[j] ^ karr[j - 1]; 74 karr[j] = karr[j] ^ karr[j - 1]; 75 } 76 } 77 } 78 } 79 80 /** 81 * 冒泡法排序直接返回第 K-1 元素 82 * 83 * @param arr 84 * @param k 85 * @return 86 * @throws Exception 87 */ 88 public static int kmax1(int[] arr, int k) throws Exception { 89 try { 90 if (k <= 0 || k > arr.length) { 91 throw new Exception("k value out of range!"); 92 } 93 BubbleMaxToMin(arr); 94 System.out.println(Arrays.toString(arr)); 95 return arr[k - 1]; 96 } catch (Exception e) { 97 // TODO: handle exception 98 throw e; 99 } 100 101 } 102 103 }