本文截取自:https://mp.weixin.qq.com/s?__biz=MzIwNTc4NTEwOQ==&mid=2247486030&idx=1&sn=a5b2d98f595ad049f0b55cdefb930365&chksm=972adb34a05d522270879c2bf7990a25b7433d738ce5f52f23a3e48b53f74c73be8075e7e148&scene=0&subscene=131&ascene=7&devicetype=android-26&version=26070334&nettype=WIFI&abtest_cookie=BAABAAoACwANABMABAAllx4AV5keAICZHgCJmR4AAAA%3D&lang=zh_CN&pass_ticket=Z8SghZSiaU7M1Wgtfag%2B5uGPoJmq92mdfwDxVHw%2BoJnZ2wPEZZkDHzsPJ4NbhA7H&wx_header=1

TopN.java
public class TopN {
// 父節點 private int parent(int n) { return (n - 1) / 2; } // 左孩子 private int left(int n) { return 2 * n + 1; } // 右孩子 private int right(int n) { return 2 * n + 2; } // 構建堆 private void buildHeap(int n, int[] data) { for(int i = 1; i < n; i++) { int t = i; // 調整堆 while(t != 0 && data[parent(t)] > data[t]) { int temp = data[t]; data[t] = data[parent(t)]; data[parent(t)] = temp; t = parent(t); } } } // 調整data[i] private void adjust(int i, int n, int[] data) { if(data[i] <= data[0]) { return; } // 置換堆頂 int temp = data[i]; data[i] = data[0]; data[0] = temp; // 調整堆頂 int t = 0; while( (left(t) < n && data[t] > data[left(t)]) || (right(t) < n && data[t] > data[right(t)]) ) { if(right(t) < n && data[right(t)] < data[left(t)]) { // 右孩子更小,置換右孩子 temp = data[t]; data[t] = data[right(t)]; data[right(t)] = temp; t = right(t); } else { // 否則置換左孩子 temp = data[t]; data[t] = data[left(t)]; data[left(t)] = temp; t = left(t); } } } // 尋找topN,該方法改變data,將topN排到最前面 public void findTopN(int n, int[] data) { // 先構建n個數的小頂堆 buildHeap(n, data); // n往后的數進行調整 for(int i = n; i < data.length; i++) { adjust(i, n, data); } } // 打印數組 public void print(int[] data) { for(int i = 0; i < data.length; i++) { System.out.print(data[i] + " "); } System.out.println(); } } Main.java import java.util.Random; /** * @author xiaoshi on 2018/10/14. */ public class Main { public static void main(String[] args) { TopN topN = new TopN(); // 第一組測試 int[] arr1 = new int[]{56, 30, 71, 18, 29, 93, 44, 75, 20, 65, 68, 34}; System.out.println("原數組:"); topN.print(arr1); topN.findTopN(5, arr1); System.out.println("調整后數組:"); topN.print(arr1); // 第二組測試 int[] arr2 = new int[1000]; for(int i=0; i<arr2.length; i++) { arr2[i] = i + 1; } System.out.println("原數組:"); topN.print(arr2); topN.findTopN(50, arr2); System.out.println("調整后數組:"); topN.print(arr2); // 第三組測試 Random random =new Random(); int[] arr3 = new int[1000]; for(int i=0; i<arr3.length; i++) { arr3[i] = random.nextInt(); } System.out.println("原數組:"); topN.print(arr3); topN.findTopN(50, arr3); System.out.println("調整后數組:"); topN.print(arr3); } } 運行結果: 原數組: 56 30 71 18 29 93 44 75 20 65 68 34 調整后數組: 65 68 71 75 93 18 29 30 20 44 56 34 原數組: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 調整后數組: 951 952 955 954 953 956 957 963 968 964 972 961 979 959 958 967 966 969 974 965 970 973 988 962 983 993 986 981 987 992 960 976 1000 982 978 977 975 985 984 990 971 997 996 991 989 999 998 980 994 995 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 原數組: 835636999 -90522479 -769818338 -1416245398 1041573706 1812203535 896607110 1789246766 1774883884 26722194 -418633859 1344767118 1570967674 1316806558 -1435502178 1473470755 -918439629 1869702742 2101404773 -1296472335 649689400 1153902366 -1052670714 498645159 -1530905537 -1159220094 -154125959 -868393434 -504505075 -1106082731 -494609447 -1406763201 -750828828 -342445539 -744595730 -1920006464 -1230413255 -1426324562 -1277878264 474935729 -2029054806 447026196 -1121975794 -1448358181 1957166126 1336854710 …… 調整后數組: 1960093727 1964906931 1970688292 1975808864 1981745799 1991241336 2022661667 1981095418 1998580270 1988169