当前位置:   article > 正文

堆的应用----TopK问题和堆排序_堆一般维护topk,或者堆排序

堆一般维护topk,或者堆排序

用堆的数据结构常见解决问题是  TopK  和堆排序。

1 TopK 问题  

   此问题需要在N个数中找出最大或者最小的K 个数。这里我们用找最大的K个数来举例。

  1. void AdjustDown(int* hp, int K, int i)
  2. {
  3. int parent = i;
  4. int child = i * 2 + 1;
  5. while (child < K)
  6. {
  7. if (child + 1 < K&&hp[child + 1] < hp[child])
  8. {
  9. ++child;
  10. }
  11. if (hp[parent]>hp[child])
  12. {
  13. swap(hp[child], hp[parent]);
  14. parent = child;
  15. child = parent * 2 + 1;
  16. }
  17. else
  18. {
  19. break;
  20. }
  21. }
  22. }
  23. ///TopK问题
  24. void TopK()
  25. {
  26. const int N = 1000; // 假设给随机1000个数
  27. const int K = 5; //找最大的5个数
  28. int a[N] = {0};
  29. for (int i = 0; i < N; ++i)
  30. {
  31. a[i] = rand() % 1000; //创建数组a[]
  32. }
  33. a[2] = 5000; //给定几个最大的数,以便测试代码时,这几个数一定在其中
  34. a[62] = 1020;
  35. a[996] = 8888;
  36. a[452] = 9999;
  37. int hp[K] = { 0 };
  38. for (int i = 0; i < K; ++i) //用a[]数组中的K个数创建hp[]这个数组
  39. {
  40. hp[i] = a[i];
  41. }
  42. for (int i = (K - 2) >> 2; i >= 0; --i) 用数组hp建立小堆
  43. {
  44. AdjustDown(hp, K, i);
  45. }
  46. for (size_t i = K; i < N; ++i) 拿建好的小堆与a[]数比较。(小堆时,hp[0]是堆中最小的数,只要a[i]比它大就交换)
  47. {
  48. if (a[i]>hp[0])
  49. {
  50. hp[0] = a[i];
  51. AdjustDown(hp, K, 0);
  52. }
  53. }
  54. for (size_t i = 0; i < K; ++i) 打印这个堆,可以看到最大的五个数
  55. {
  56. cout << hp[i] << " ";
  57. }
  58. cout << endl;
  59. }

2堆排序问题

思路:若把一组数从小到大排列---》先建立大堆-----》a[0]是堆顶,a[end]是堆的最后一个数,两个交换-----》除去最后一个进行向下调整---》--end  ,直到end为0

  1. void AdjustDown1(int* b, int n, int i) //向下调整,建立大堆
  2. {
  3. int parent = i;
  4. int child = parent * 2 + 1;
  5. while (child < n)
  6. {
  7. if (child + 1 < n&&b[child + 1] > b[child])
  8. {
  9. ++child;
  10. }
  11. if (b[child]>b[parent])
  12. {
  13. swap(b[child], b[parent]);
  14. parent = child;
  15. child = parent * 2 + 1;
  16. }
  17. else
  18. {
  19. break;
  20. }
  21. }
  22. }
  23. int b[] = { 10, 11, 1, 2, 3, 85, 96, 4, 23, 52 };
  24. void SortHeap(int* b, size_t n)//堆排序 升序 --》建立大堆
  25. {
  26. for (int i = (n - 2) >> 2; i >= 0; --i)//建堆
  1. {
  2. AdjustDown1(b, n, i);
  3. }
  4. int end = n - 1; //end 为最后一个数的下标
  5. while (end) //不断的取堆顶最大的数放到后面,--end,调整堆。
  6. {
  7. swap(b[0], b[end]);
  8. AdjustDown1(b, end,0);
  9. --end;
  10. }
  11. for (int i = 0; i < n; ++i)
  12. {
  13. cout << b[i] << " ";
  14. }
  15. cout << endl;
  16. }

结果:1TopK:


2 堆排序:


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

闽ICP备14008679号