Java范例 从20亿个随机整数中找出最小的1000个整数只需要1.2秒的时间

本文介绍了一种使用大顶堆算法高效查找数组中最小的TopK个元素的方法。通过构建并调整大顶堆,算法能快速筛选出目标元素,适用于大规模数据集的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查找算法:大顶堆

package com.contoso;

import java.util.Arrays;
import java.util.Random;

public class RankingMinimum {

    /**
     * 创建堆
     */
    public static void buildMaxHeap(int[] result) {
        if (result == null || result.length <= 1) {
            return;
        }
        //从最后的一个非叶子节点向上开始排,避免迭代没有意义的叶子节点
        int half = (result.length - 1) / 2;
        for (int i = half; i >= 0; i--) {
            maxHeap(result, result.length, i);
        }
    }

    /**
     * 调整堆(沉降法)
     */
    public static void maxHeap(int[] result, int heapSize, int index) {
        int left = index * 2 + 1;
        int right = index * 2 + 2;
        int max = index;
        //判断有没有左节点,如若有则比较替换max
        if (left < heapSize && result[left] > result[max]) {
            max = left;
        }
        //判断有没有右节点,如若有则max和右节点比较,注意max有可能是left也有可能是index
        if (right < heapSize && result[right] > result[max]) {
            max = right;
        }

        if (index != max) {
            int temp = result[index];
            result[index] = result[max];
            result[max] = temp;
            //被替换的max节点所在的堆,需要重新调整,使小值/大值一直下沉
            maxHeap(result, heapSize, max);
        }

    }

    /**
     * 最大堆法 利用树形的特点保存前面比较的结果,可以减少比较次数
     */
    public static void findTopMininum(int[] data, int top) {
        int[] result = new int[top];
        // 最先遍历的top个数放入数组中
        for (int i = 0; i < top; i++) {
            result[i] = data[i];
        }
        // 构建前top个数的最大堆
        buildMaxHeap(result);
        // i - top个数和前面和top中最大数比较
        for (int i = top; i < data.length; i++) {
            // 如果堆顶大于i - top中数,则交换位置
            if (result[0] > data[i]) {
                result[0] = data[i];
                //调整堆,堆顶被替换了,加入被替换的值非常小,会一直下沉到叶子节点.
                maxHeap(result, result.length, 0);
            }

        }
        // 从小到大地打印输出结果
        sortPrint(result, top);
    }

    /**
     * 从小到大地打印输出结果
     */
    public static void sortPrint(int[] result, int top) {
        Arrays.sort(result);
        // 输出最小的TOP个数
        for (int i = 0; i < top; i++) {
            System.out.println(result[i]);
        }
    }

    public static void main(String[] args) {

        int TOP = 1000; // 查找出TOP个最小的数
        int ROWS = 2000000000; // 定义随机生成20亿个整数
        int[] initData = new int[ROWS];
        // 生成随机数
        for (int i = 0; i < ROWS; i++) {
            initData[i] = new Random().nextInt(Integer.MAX_VALUE);
        }
        long startTime = System.nanoTime();
        findTopMininum(initData, TOP);
        long endTime = System.nanoTime();
        double timeTaken = (endTime - startTime) / 1e9;
        System.out.println("Time Taken in seconds:" + timeTaken);
    }

}
run:
0
1
2
4
5
11
11
11
12
13
14
15
16
18
18
21
21
22
25
30
30
30
32
32
32
33
34
34
36
36
39
39
39
40
40
40
40
40
42
42
48
48
49
49
51
51
57
57
58
60
62
63
63
63
63
63
64
66
67
67
71
72
73
74
74
74
75
76
76
80
80
81
82
83
83
84
85
86
86
89
90
91
91
91
98
99
99
100
101
103
103
103
105
105
105
105
107
107
109
109
109
111
112
112
113
114
114
116
116
116
117
119
121
121
121
121
122
125
126
126
126
127
127
129
133
135
135
136
138
139
139
141
141
141
142
144
146
147
148
149
154
155
155
156
156
157
157
158
158
162
163
163
165
167
168
168
168
169
170
170
171
173
173
173
179
179
180
180
182
186
187
188
190
192
193
194
194
194
199
200
200
201
202
203
205
206
207
208
208
209
209
212
212
213
213
213
213
218
218
218
220
220
220
220
221
224
226
227
228
228
229
230
232
233
233
234
234
235
235
237
237
238
239
240
241
247
248
249
249
252
252
252
253
253
254
255
258
259
259
260
261
262
262
262
264
265
266
266
267
268
269
270
270
274
275
276
276
278
282
284
284
285
288
289
289
290
291
291
293
297
299
299
299
300
300
300
301
304
308
310
310
315
316
317
318
319
319
320
321
326
326
327
327
328
329
332
336
336
337
338
339
341
345
349
349
350
351
352
353
355
355
356
356
359
360
360
361
361
361
361
362
362
362
362
363
363
364
364
364
365
366
367
367
368
368
368
369
369
370
371
373
375
376
377
378
379
379
382
385
385
385
387
387
389
390
391
391
391
392
393
393
393
394
396
398
400
401
402
403
403
403
404
404
405
406
409
409
410
410
411
411
411
413
413
415
415
416
417
417
418
418
418
418
419
422
422
423
424
424
425
427
428
429
429
429
429
430
433
433
435
435
436
436
437
437
439
440
440
442
443
444
446
447
448
448
449
449
454
454
454
454
455
455
456
457
457
458
460
461
463
464
465
466
467
467
468
471
473
475
479
480
480
480
482
483
485
486
486
486
486
491
491
492
492
493
493
493
494
497
497
499
504
505
506
507
508
508
509
509
509
510
512
515
515
516
518
519
520
521
522
523
523
524
524
525
525
526
527
528
528
528
529
529
530
531
532
533
536
536
537
540
543
543
544
545
547
550
552
553
554
554
554
554
555
556
556
557
558
559
559
561
562
563
564
565
566
567
567
567
569
570
572
574
575
576
576
576
577
577
583
585
586
586
586
588
590
590
591
592
592
594
594
595
596
599
599
602
602
602
602
603
604
605
606
609
610
610
610
611
611
611
614
615
616
616
617
617
620
620
621
622
622
623
623
625
625
629
629
631
634
635
635
635
635
636
638
638
638
639
640
641
641
643
644
645
647
649
651
652
653
653
656
658
660
662
664
665
665
666
667
670
671
671
671
673
674
675
676
676
679
679
680
680
684
684
684
685
685
687
687
687
688
691
691
694
694
695
698
699
700
701
702
703
703
705
708
709
710
710
711
713
714
714
714
715
715
715
718
719
719
719
721
722
724
724
724
724
724
726
727
730
730
734
734
735
735
736
736
736
736
736
738
741
741
741
741
741
742
742
743
744
746
746
746
746
747
748
748
750
751
753
753
754
755
756
758
759
759
761
761
763
763
766
766
767
767
770
773
775
776
777
777
778
779
780
780
781
782
783
786
790
790
791
793
793
794
797
797
798
800
800
801
802
803
805
806
807
808
810
811
811
813
813
814
815
816
816
817
817
818
819
822
822
823
828
828
829
829
830
830
833
836
837
839
840
842
842
842
843
846
846
849
850
851
851
852
855
856
859
862
863
866
867
868
870
871
872
874
875
876
877
878
878
879
880
881
881
881
883
884
886
890
891
892
893
893
895
895
897
901
902
905
906
906
907
907
907
908
909
910
911
911
913
913
914
915
916
917
918
920
923
923
927
928
929
931
933
934
935
936
941
941
942
944
949
950
950
952
953
955
956
958
958
960
960
961
962
963
963
964
964
965
967
968
968
968
973
976
978
978
979
981
981
983
984
986
986
988
988
988
990
991
991
992
994
995
996
999
999
1002
1003
1005
1005
1006
1007
1009
1010
1011
1011
1011
1012
1012
1012
1012
1013
1015
1016
1017
1017
1017
1018
1019
1019
1020
1021
1022
1024
1024
1024
1026
1027
1027
1029
1029
1031
1032
1033
1034
1037
1040
1040
1041
1042
1043
1044
1045
1046
1046
1048
1050
1051
1051
1052
1053
1054
1058
1058
1059
1059
1061
1061
1063
1064
1065
1066
1066
1067
1068
1068
1072
1073
1073
1075
1076
1077
1078
1078
1079
1079
1081
Time Taken in seconds:1.271427872
BUILD SUCCESSFUL (total time: 1 minute 49 seconds)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值