DataStructureAndAlgorithm--第 K 个最大值

设有一组 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 }

 

posted @ 2017-04-03 23:30  MicroCat  阅读(409)  评论(0编辑  收藏  举报