堆的简单应用
2016-05-13 10:31
274 查看
一、大数据的处理
给出N个数据,要求找到并输出这N个数里面最大的K个数
思路:利用堆,先建一个开辟一个大小为K的数组,从N个数据里拿出K个数据放到堆里面,然后再通过向
下调整法把堆调整为最小堆,此时数组的第一个元素就是堆里面最小的元素,然后在剩下的N-K个
数据中依次和堆里面最小的数据进行比较,若比第一个元素大,则交换两个的值,每交换一次就向下调
整一次,保证在最上面的是最小元素,这样一直到所有数据比较完毕,此时堆里面存储的k个数据就是最
大的k个数据。
下面是实现代码
为了便于调试,我用的测试栗子比较简单,大家可以尝试一下更一般的栗子哦~
二.堆排序
思路:利用堆,建一个最大堆,每次选出最大的数据与数组末尾的数据进行交换,然后再进行一次向下
调整变成最大堆,始终保持最上面的为当前最大的数据,假设数组由n个数据,则下次就让第一个数据与
数组的第n-1个数据作比较,因为第n个数据已经是最大的了,每交换一次要调整一次,这样当比较到第
一个数据时这个堆就是一个有序的了。
实现代码如下:
测试代码:
测试结果:
以上便是堆的两种简单应用啦,不足之处还请大家指出哦~
给出N个数据,要求找到并输出这N个数里面最大的K个数
思路:利用堆,先建一个开辟一个大小为K的数组,从N个数据里拿出K个数据放到堆里面,然后再通过向
下调整法把堆调整为最小堆,此时数组的第一个元素就是堆里面最小的元素,然后在剩下的N-K个
数据中依次和堆里面最小的数据进行比较,若比第一个元素大,则交换两个的值,每交换一次就向下调
整一次,保证在最上面的是最小元素,这样一直到所有数据比较完毕,此时堆里面存储的k个数据就是最
大的k个数据。
下面是实现代码
#include<iostream> #include<algorithm> using namespace std; //1.在N个数据当中找出最大的K个数 const int N = 10000; const int K = 100; void AdjustDown1(int a[], int size, int parent) //建一个小堆 { int child = parent * 2 + 1; while (child < K) { if ((child + 1 < K) && (a[child + 1] < a[child])) { child++; } if (a[child] < a[parent]) { swap(a[child], a[parent]); parent = child; child = parent * 2 + 1; } else { break; } } } void GetTopK(int a[],int TopK[]) { assert(K < N); int i = 0; int j = 0; int m = 0; int n = 0; for (i = 0; i < K; i++) { TopK[i] = a[i]; //取出a中的前k个数字放到topk[]里面 } //建堆 for (j = (K - 2) / 2; j >0; --j) { AdjustDown1(TopK,K,j); } for (int m = 0; m < N; ++m) { if (a[m]>TopK[0]) { TopK[0] = a[m]; AdjustDown1(TopK, K, 0); } } for (int n = 0; n < K; ++n) //一次输出K个最大数 { cout << TopK << " "; } cout << endl; }测试代码
#include"BIgData.h" void TestTopK() { int a ; int TopK[K]; for (int i = 0; i < N; ++i) { a[i] = i; } GetTopK(a, TopK); } int main() { TestTopK(); system("pause"); return 0; }测试结果
为了便于调试,我用的测试栗子比较简单,大家可以尝试一下更一般的栗子哦~
二.堆排序
思路:利用堆,建一个最大堆,每次选出最大的数据与数组末尾的数据进行交换,然后再进行一次向下
调整变成最大堆,始终保持最上面的为当前最大的数据,假设数组由n个数据,则下次就让第一个数据与
数组的第n-1个数据作比较,因为第n个数据已经是最大的了,每交换一次要调整一次,这样当比较到第
一个数据时这个堆就是一个有序的了。
实现代码如下:
//2.堆排序:建大堆,每次找到最大的数据交换到数组末尾,将剩下的数据AdjustDown,再进行交换 void AdjustDown2(int a[],int size,size_t parent) { int child = parent * 2 + 1; while (child<size) { if ((child + 1 < size)&&a[child] < a[child + 1]) { ++child; } if (a[child] > a[parent]) { swap(a[child], a[parent]); parent = child; child = parent * 2 + 1; } else { break; } } } void Heap_Sort(int a[], size_t n) { for (int i = (n - 2) / 2; i >= 0; i--) //注意边界条件 { AdjustDown2(a, n, i); } for (int i = 0; i < n; ++i) { swap(a[0], a[n - 1-i]); AdjustDown2(a, n - 1 - i, 0); } for (int i = 0; i < n; ++i) { cout << a[i] << " "; } cout << endl; }
测试代码:
void TestHeap_Sort() { int a[] = { 10, 12, 9, 15, 13, 17, 16, 18, 20,14 }; Heap_Sort(a, 10); } int main() { TestHeap_Sort(); system("pause"); return 0; }
测试结果:
以上便是堆的两种简单应用啦,不足之处还请大家指出哦~
相关文章推荐
- 堆排序
- C#实现将数组内元素打乱顺序的方法
- C#堆排序实现方法
- jQuery删除一个元素后淡出效果展示删除过程的方法
- jQuery拖动元素并对元素进行重新排序
- Perl中怎样从数组中删除某个值?
- PHP的数组中提高元素查找与元素去重的效率的技巧解析
- javascript学习笔记(十八) 获得页面中的元素代码
- javascript实现在某个元素上阻止鼠标右键事件的方法和实例
- jQuery验证元素是否为空的两种常用方法
- JavaScript实现获取某个元素相邻兄弟节点的prev与next方法
- jQuery on()绑定动态元素出现的问题小结
- jQuery经过一段时间自动隐藏指定元素的方法
- jQuery使用之设置元素样式用法实例
- jQuery判断元素上是否绑定了指定事件的方法
- jQuery统计指定子元素数量的方法
- jQuery选择id属性带有点符号元素的方法
- jQuery使用之标记元素属性用法实例
- 从零开始学习jQuery (四) jQuery中操作元素的属性与样式
- jQuery对指定元素中指定字符串进行替换的方法