第三章:查詢與排序(下)----------- 3.25 知其然知其所以然:小頂堆與topK的具體程式碼實現
小頂堆與topK的具體程式碼實現:
求海量資料(正整數)按逆序排列的前k個數(TopK),因為數量太大,不能全部儲存在記憶體中,只能一個一個地從磁碟或者網路上讀取資料,請設計一個高效的演算法來解決這個問題。
第一行:使用者輸入K,代表要求得topK。
隨後的N(不限制)行,每一行是一個整數,代表使用者輸入的資料。
使用者輸入-1代表輸入終止。
請輸出topK,從小到大,空格分割。
解決:大頂堆。
思路:
輸入N個資料時,若n<k,依次新增到陣列(堆)當中;當填入資料達到k時,立刻堆化。
若n>k,比較要填入數與堆頂資料,若x>heap[0],將heap[0]賦值為x,並向下堆化。
ps:n:已填入資料的數量。
程式碼:
#include<iostream>
using namespace std;
int* heap; //全域性變數 ===> 陣列頭指標(陣列名)
int size=0;
int k; //輸出前k個數
/*******/
void deal(int x);
void makeMinHeap(int A[],int length);
void MinHeapFixDown(int A[],int i,int n);
void printRs();
/*******/
int main(){
std::ios_base::sync_with_stdio(false);
cin>>k;
heap=new int[k]; // 動態建立陣列
int x;
while((cin>>x)&&x!=-1){
deal(x); //處理x
}
printRs();
return 0;
}
/*
如果資料的數量小等於k,直接加入堆中
等於k的時候,進行堆化
*/
void deal(int x){
if(size<k){
heap[size++]=x;
if(size==k){
//堆化
makeMinHeap(heap,k);
}
}
else{
//x和堆頂進行比較,如果x大於堆頂,x將堆頂擠掉,並向下調整
if(heap[0]<x){
heap[0]=x;
MinHeapFixDown(heap,0,k);
printRs();
}
}
}
void printRs(){
for(int i=0;i<k;i++){
cout<<heap[i]<<" ";
}
cout<<endl;
}
void makeMinHeap(int A[],int length){
int n=length;
for(int i=n/2-1;i>=0;i--){
MinHeapFixDown(A,i,n);
}
}
//向下調整函式
void MinHeapFixDown(int A[],int i,int n){
//找到左右孩子
int left=2*i+1;
int right=2*i+2;
//左孩子已經越界,i就是葉子節點
if(left>=n){
return;
}
int min=left;
if(right>=n){
min=left;
}
else{
if(A[right]<A[left]){
min=right;
}
}
//min指向了左右孩子中較小的那個
//如果A[i]比兩個孩子都要小,不用調整
if(A[i]<A[min]){
return;
}
//否則,找到兩個孩子中較小的,和i交換
int temp=A[i];
A[i]=A[min];
A[min]=temp;
//小孩子那個位置的值發生了變化,i變更為小孩子的那個位置,遞迴調整
MinHeapFixDown(A,min,n);
}
結果:
相關文章
- 小頂堆與topK的具體程式碼實現《演算法很美》TopK演算法
- 第三章:查詢與排序(下)----------- 3.16堆的概念及堆排序思路排序
- 第三章:查詢與排序(下)----------- 3.20桶排序排序
- 第三章:查詢與排序(下)----------- 3.19 計數排序排序
- 第三章:查詢與排序(下)----------- 3.21基數排序排序
- 第三章:查詢與排序(下)----------- 3.28 特殊排序(利用sort函式)排序函式
- 第三章:查詢與排序(下)----------- 3.14 逆序對個數排序
- 第三章:查詢與排序(下)----------- 3.12 實踐_最小可用id是多少排序
- 知其然知其所以然之LinkedList常用原始碼閱讀原始碼
- 知其然知其所以然之ArrayList常用原始碼閱讀原始碼
- 第三章:查詢與排序(下)----------- 3.9 最快效率求出亂序陣列中第k小的數排序陣列
- 第三章:查詢與排序(下)----------- 3.22 總結:10種排序演算法的對比分析排序演算法
- 第三章:查詢與排序(下)----------- 3.23 相關題解:排序陣列中找和的因子排序陣列
- 第三章 :查詢與排序-------3.6快排在工程實踐中的優化排序優化
- 第三章 :查詢與排序-------3.2你需要掌握的快速排序演算法排序演算法
- 大根堆和堆排序的原理與實現排序
- 第三章:查詢與排序(下)----------- 3.15基礎學習_樹、二叉樹、堆排序排序二叉樹
- 雲開發與 WePY,快速實現 Linux 命令查詢小程式Linux
- 雲開發與WePY,快速實現Linux命令查詢小程式Linux
- 第三章:查詢與排序(下)----------- 3.29 題解:判斷陣列的包含問題排序陣列
- 第二章 :查詢與排序---------遞迴、查詢與排序補充排序遞迴
- 第三章:查詢與排序(下)----------- 3.27 用計數排序解決員工年齡問題排序
- 第三章:查詢與排序(下)----------- 3.11 趣味擴充_尋找發帖水王排序
- 第三章 :查詢與排序-------3.7分治模式的完美詮釋_歸併排序排序模式
- BST查詢結構與折半查詢方法的實現與實驗比較
- 堆的原理與實現
- 第三章:查詢與排序(下)----------- 3.10 實戰解題_哪個數字超過了一半?排序
- 第三章 :查詢與排序(下)-------3.1分治法介紹及關鍵點解析排序
- 堆與堆排序(一)排序
- Sql 查詢 置頂、排序,置頂和非置頂為不同的排序欄位SQL排序
- Android圖片載入庫Glide 知其然知其所以然 開篇AndroidIDE
- 大頂堆的python實現Python
- Redis 設計與實現 (八)--排序、慢查詢日誌、監視器Redis排序
- 第三章 :查詢與排序-------3.5快排之三指標分割槽法排序指標
- 第二章 :查詢與排序-------希爾排序排序
- 看懂堆排序——堆與堆排序(三)排序
- Android 圖片載入庫Glide知其然知其所以然之載入AndroidIDE
- MySQL 隨機查詢資料與隨機更新資料實現程式碼MySql隨機