寻找最大或最小的K个数-创新互联
题目描述
网站建设、成都网站建设介绍好的网站是理念、设计和技术的结合。创新互联建站拥有的网站设计理念、多方位的设计风格、经验丰富的设计团队。提供PC端+手机端网站建设,用营销思维进行网站设计、采用先进技术开源代码、注重用户体验与SEO基础,将技术与创意整合到网站之中,以契合客户的方式做到创意性的视觉化效果。:在好几亿个数据中找出大或最小的K个数。
分析:这几亿的数据肯定不能一起加载到内存中去,更不能对这些数据直接进行排序,因此我们这里讲用数据结构中的 堆 来解决这个问题。
假定这里要从100000个数据中找出大的100个数据,这样是为了描述方便,我们这里直接用一个数组来存储这个100000个数据,如果数据多达好几亿,则只需将这些数据放入文件中进行读写即可,这里为了描述问题方便就这样假定。
步骤:
取出这些数据中前100个数据,然后用这些数据建立一个小堆;
从第101个数据开始,每读取一个数据,就与堆顶的元素进行比较,如果该数据大于堆顶的数据,则将堆顶的数据替换为该数据,并对这个小堆进行调整。
重复步骤2,等到所有数据都取完后,则留下的这个堆中的100个元素,就是我们要得到的大的100个数。
代码如下:
#pragma once #include#include using namespace std; #define N 100000 //N个数据 #define K 100 //大或最小数据的个数 //仿函数,可以选大的K个数,也可以选最小的K个数 template struct Less { bool operator()(const T& num1, const T& num2) { return num1 < num2; } }; template struct Greater { bool operator()(const T& num1, const T& num2) { return num1 > num2; } }; template //默认建小堆 class Heap { public: Heap(const T* a, size_t size) :MaxOrMinK(new T[size]) , _size(size) { for (size_t i = 0; i < _size; ++i) { MaxOrMinK[i] = a[i]; } } ~Heap() { if (_size > 0) delete[] MaxOrMinK; } void CreatHeap() // 建堆,(小/大) { for (int i = (_size - 2) / 2; i >= 0; --i) { AdjustDown(MaxOrMinK, _size, i); } } void GetK(const T* array, size_t size) //从array中选出大(或最小)的K个数 { for (int i = K; i < size; ++i) { if (com()(MaxOrMinK[0], array[i])) { MaxOrMinK[0] = array[i]; AdjustDown(MaxOrMinK, _size, 0); } } } void Print() { if (_size > 0) { for (size_t i = 0; i < _size; ++i) { cout << MaxOrMinK[i] << endl; } } } protected: void AdjustDown(T*& a, size_t size, size_t root) { size_t child = root * 2 + 1; //计算左孩子 while (child < size) { if (child + 1 < size && com()(a[child + 1], a[child])) { ++child; } if (com()(a[child], a[root])) { std::swap(a[root], a[child]); root = child; child = root * 2 + 1; } else { break; } } } private: T* MaxOrMinK; size_t _size; }; void Test1() { int randNum[N]; srand(time(NULL)); for (int i = 0; i < N; ++i) { int tmp = rand() % 10000; randNum[i] = tmp; //产生N个10000以内的随机数 } Heap > get_K(randNum, K); //小堆 选大的K个数 get_K.CreatHeap(); get_K.GetK(randNum, N); get_K.Print(); } void Test2() { int randNum[N]; srand(time(NULL)); for (int i = 0; i < N; ++i) { int tmp = rand() % 10000; randNum[i] = tmp; //产生N个10000以内的随机数 } Heap > get_K(randNum, K); //大堆 选最小的K个数 get_K.CreatHeap(); get_K.GetK(randNum, N); get_K.Print(); }
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。
本文题目:寻找最大或最小的K个数-创新互联
分享链接:http://azwzsj.com/article/dpccdh.html