采用小頂堆
public class TopN { /** * 找出數組arr中最大的前n個值,不要求這n個值有序 */ public static int[] topN(int[] arr, int n) { /** * 構建堆積 */ int[] list = new int[n]; System.arraycopy(arr, 0, list, 0, n); // 在堆頂的始終是最小的值 for (int i = 0; i < n; i++) { int t = i; while (t != 0 && list[parent(t)] > list[t]) { swap(list, t, t = parent(t)); } } /** * 小頂堆 */ for (int i = n, len = arr.length; i < len; i++) { if (arr[i] >= list[0]) { // 置換棧頂 list[0] = arr[i]; // 調整棧頂 int t = 0; // left(t) < n 防止下標越界 while ((left(t) < n && list[t] > list[left(t)]) || (right(t) < n && list[t] > list[right(t)])) { // 比較右節點和左節點值值,把小的節點值和父節點值對調 if (right(t) < n && list[right(t)] < list[left(t)]) { swap(list, t, t = right(t)); } else { swap(list, t, t = left(t)); } } } } return list; } private static void swap(int[] list, int i, int j) { int tmp = list[i]; list[i] = list[j]; list[j] = tmp; } /** * 父節點索引 */ private static int parent(int i) { return (i - 1) / 2; } /** * 左孩子索引 */ private static int left(int i) { return 2 * i + 1; } /** * 右孩子索引 */ private static int right(int i) { return 2 * i + 2; } public static void main(String[] args) { int[] arr = new int[] { 1, 2, 23, 4, 5, 11, 12, 13, 100 }; System.out.println("原始數組: "); System.out.println(Arrays.toString(arr)); System.out.println("調整后數組: "); System.out.println(Arrays.toString(TopN.topN(arr, 3))); } }