当前位置:   article > 正文

Top K问题 ----堆排序_减治法求解堆排序

减治法求解堆排序

问题大致描述:

在海量数据中选出前K个最大的数据

输入:

    第一行:输入K,表示要求选出的K个最大的数

    第二行:输入一个数

     ......

    第n-1行:输入一个数

    第n行:输入-1表示结束

(其中K要<=输入的个数)

输出:

  输出前K的最大的数

 

思路:因为要在海量的数据中选出K个数,所以可以利用堆排序,建立小根堆,

在用户输入的数小于k的时候,则不需要选出K个数,直接保存到数组中即可

在用户输入k个数的时候,直接用数组建立一个小根堆,则arr[0]就是其最小的数

若用户输入的数>K的时候,需要用输入的数与arr[0]做比较:

                                           如果输入的数大于arr[0],则将输入的数赋值给arr[0],并调整小根堆

                                           如果输入的数小于等于arr[0],无需操作

 

Java代码:

  1. import java.util.Scanner;
  2. /**
  3. * 前K个数
  4. * TopK
  5. *
  6. */
  7. public class Main {
  8. static int[] heap; //保存前K的数的数组
  9. static int index = 0; //标记数组中最后一个元素的位置
  10. static int k;
  11. public static void main(String[] args) {
  12. Scanner in = new Scanner(System.in);
  13. k = in.nextInt(); //输入k
  14. heap = new int[k];
  15. int x = in.nextInt();
  16. while(x!=-1) {
  17. deal(x); //处理x
  18. x = in.nextInt();
  19. }
  20. printRs();
  21. }
  22. //打印输出K个数
  23. public static void printRs() {
  24. for(int i = 0; i < heap.length; i++)
  25. System.out.print(heap[i] + " ");
  26. }
  27. //对x进行处理
  28. public static void deal(int x) {
  29. if(index<k) {
  30. heap[index++] = x;
  31. //当index==k时需要立即进行堆化
  32. if(index==k) {
  33. //堆化
  34. MakeMinHeap(heap);
  35. index++;
  36. }
  37. return;
  38. }
  39. //x和堆顶进行比较,若x大于堆顶,x将堆顶挤掉并向下调整
  40. if(heap[0]<x) {
  41. heap[0] = x;
  42. MinHeapFixDown(heap, 0);
  43. }
  44. }
  45. //堆化,一般这个方法只在初始的时候使用一次就行
  46. public static void MakeMinHeap(int[] arr) {
  47. int n = arr.length;
  48. for(int i = n/2-1;i>=0;i--)
  49. MinHeapFixDown(arr,i);
  50. }
  51. //调整堆,使堆形成小根堆
  52. public static void MinHeapFixDown(int[] arr,int i) {
  53. int n = arr.length;
  54. //先找到左右孩子
  55. int left = 2*i+1;
  56. int right = 2*i+2;
  57. if(left>=n) //若左孩子已经越界,i就是叶子节点
  58. return;
  59. int min = left;
  60. if(right>=n) //若右孩子越界,则左孩子就是最小的
  61. min = left;
  62. else if(arr[right]<arr[left])
  63. min = right;
  64. //这样min指向左右孩子中较小的那个
  65. //如果arr[i]比两个孩子都要小,不用调整
  66. if(arr[i]<=arr[min])
  67. return;
  68. //否则,找到两个孩子中较小的,和i交换
  69. int temp = arr[i];
  70. arr[i] = arr[min];
  71. arr[min] = temp;
  72. //小孩子那个位置的值发送了变化,i变更为小孩子那个位置,递归调整
  73. MinHeapFixDown(arr,min);
  74. }
  75. }

 

总结:

做这个题,必须熟练掌握堆排序的内容!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/804080
推荐阅读
相关标签
  

闽ICP备14008679号