題目描述
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括二道網(wǎng)站建設(shè)、二道網(wǎng)站制作、二道網(wǎng)頁(yè)制作以及二道網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,二道網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到二道省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!
:在好幾億個(gè)數(shù)據(jù)中找出最大或最小的K個(gè)數(shù)。
分析:這幾億的數(shù)據(jù)肯定不能一起加載到內(nèi)存中去,更不能對(duì)這些數(shù)據(jù)直接進(jìn)行排序,因此我們這里講用數(shù)據(jù)結(jié)構(gòu)中的 堆 來(lái)解決這個(gè)問(wèn)題。
假定這里要從100000個(gè)數(shù)據(jù)中找出最大的100個(gè)數(shù)據(jù),這樣是為了描述方便,我們這里直接用一個(gè)數(shù)組來(lái)存儲(chǔ)這個(gè)100000個(gè)數(shù)據(jù),如果數(shù)據(jù)多達(dá)好幾億,則只需將這些數(shù)據(jù)放入文件中進(jìn)行讀寫(xiě)即可,這里為了描述問(wèn)題方便就這樣假定。
步驟:
取出這些數(shù)據(jù)中前100個(gè)數(shù)據(jù),然后用這些數(shù)據(jù)建立一個(gè)小堆;
從第101個(gè)數(shù)據(jù)開(kāi)始,每讀取一個(gè)數(shù)據(jù),就與堆頂?shù)脑剡M(jìn)行比較,如果該數(shù)據(jù)大于堆頂?shù)臄?shù)據(jù),則將堆頂?shù)臄?shù)據(jù)替換為該數(shù)據(jù),并對(duì)這個(gè)小堆進(jìn)行調(diào)整。
重復(fù)步驟2,等到所有數(shù)據(jù)都取完后,則留下的這個(gè)堆中的100個(gè)元素,就是我們要得到的最大的100個(gè)數(shù)。
代碼如下:
#pragma once #include#include using namespace std; #define N 100000 //N個(gè)數(shù)據(jù) #define K 100 //最大或最小數(shù)據(jù)的個(gè)數(shù) //仿函數(shù),可以選最大的K個(gè)數(shù),也可以選最小的K個(gè)數(shù) 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 //默認(rèn)建小堆 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個(gè)數(shù) { 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; //計(jì)算左孩子 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; //產(chǎn)生N個(gè)10000以?xún)?nèi)的隨機(jī)數(shù) } Heap > get_K(randNum, K); //小堆 選最大的K個(gè)數(shù) 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; //產(chǎn)生N個(gè)10000以?xún)?nèi)的隨機(jī)數(shù) } Heap > get_K(randNum, K); //大堆 選最小的K個(gè)數(shù) get_K.CreatHeap(); get_K.GetK(randNum, N); get_K.Print(); }