堆的应用----TopK问题和堆排序
2017-07-04 13:54
344 查看
用堆的数据结构常见解决问题是 TopK 和堆排序。
1 TopK 问题
此问题需要在N个数中找出最大或者最小的K 个数。这里我们用找最大的K个数来举例。
2堆排序问题
思路:若把一组数从小到大排列---》先建立大堆-----》a[0]是堆顶,a[end]是堆的最后一个数,两个交换-----》除去最后一个进行向下调整---》--end ,直到end为0
void AdjustDown1(int* b, int n, int i) //向下调整,建立大堆
{
int parent = i;
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n&&b[child + 1] > b[child])
{
++child;
}
if (b[child]>b[parent])
{
swap(b[child], b[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
int b[] = { 10, 11, 1, 2, 3, 85, 96, 4, 23, 52 };
void SortHeap(int* b, size_t n)//堆排序 升序 --》建立大堆
{
for (int i = (n - 2) >> 2; i >= 0; --i)//建堆
结果:1TopK:
2 堆排序:
1 TopK 问题
此问题需要在N个数中找出最大或者最小的K 个数。这里我们用找最大的K个数来举例。
void AdjustDown(int* hp, int K, int i) { int parent = i; int child = i * 2 + 1; while (child < K) { if (child + 1 < K&&hp[child + 1] < hp[child]) { ++child; } if (hp[parent]>hp[child]) { swap(hp[child], hp[parent]); parent = child; child = parent * 2 + 1; } else { break; } } } ///TopK问题 void TopK() { const int N = 1000; // 假设给随机1000个数 const int K = 5; //找最大的5个数 int a = {0}; for (int i = 0; i < N; ++i) { a[i] = rand() % 1000; //创建数组a[] } a[2] = 5000; //给定几个最大的数,以便测试代码时,这几个数一定在其中 a[62] = 1020; a[996] = 8888; a[452] = 9999; int hp[K] = { 0 }; for (int i = 0; i < K; ++i) //用a[]数组中的K个数创建hp[]这个数组 { hp[i] = a[i]; } for (int i = (K - 2) >> 2; i >= 0; --i) 用数组hp建立小堆 { AdjustDown(hp, K, i); } for (size_t i = K; i < N; ++i) 拿建好的小堆与a[]数比较。(小堆时,hp[0]是堆中最小的数,只要a[i]比它大就交换) { if (a[i]>hp[0]) { hp[0] = a[i]; AdjustDown(hp, K, 0); } } for (size_t i = 0; i < K; ++i) 打印这个堆,可以看到最大的五个数 { cout << hp[i] << " "; } cout << endl; }
2堆排序问题
思路:若把一组数从小到大排列---》先建立大堆-----》a[0]是堆顶,a[end]是堆的最后一个数,两个交换-----》除去最后一个进行向下调整---》--end ,直到end为0
void AdjustDown1(int* b, int n, int i) //向下调整,建立大堆
{
int parent = i;
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n&&b[child + 1] > b[child])
{
++child;
}
if (b[child]>b[parent])
{
swap(b[child], b[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
int b[] = { 10, 11, 1, 2, 3, 85, 96, 4, 23, 52 };
void SortHeap(int* b, size_t n)//堆排序 升序 --》建立大堆
{
for (int i = (n - 2) >> 2; i >= 0; --i)//建堆
{ AdjustDown1(b, n, i); } int end = n - 1; //end 为最后一个数的下标 while (end) //不断的取堆顶最大的数放到后面,--end,调整堆。 { swap(b[0], b[end]); AdjustDown1(b, end,0); --end; } for (int i = 0; i < n; ++i) { cout << b[i] << " "; } cout << endl; }
结果:1TopK:
2 堆排序:
相关文章推荐
- 堆排序在TOP K问题中的应用
- 堆与堆排序与topK问题
- 排序算法整理(6)堆排序的应用,top K 问题
- 微信红包问题求前K个元素(即堆排序的应用)
- 【面经笔记】堆排序与topk问题
- 堆排序和TopK问题
- [151225] Python3 实现最大堆、堆排序,解决TopK问题
- topK问题解法之-堆排序
- Java 实现 堆排序 快速排序 以及 TopK问题(二)
- 重温数据结构:堆,堆排序,优先队列,TopK问题
- Java 实现 堆排序 快速排序 以及 TopK问题(一)
- 堆的实现及应用(优先级队列,堆排,TopK问题)
- 《windows应用高级编程-C#编程篇》书中程序的小问题及改进
- 应用MVC设计模式解决J2ME应用程序导航问题 --mingjava
- 我在思考一个问题:用纯dhtml技术来实现信息交流平台的应用.
- ORACLE应用中常见的傻瓜问题1000问 (一)
- XMLHTTP和DOMDocument在WEB应用上的使用问题
- Java+Oracle应用开发的几个经典问题
- Tomcat 部署应用问题一网打尽
- 应用MVC模式解决J2ME导航问题[转自mingjava]