題目:輸入n個整數,輸出其中最小的k個。
例如輸入1,2,3,4,5,6,7和8這8個數字,則最小的4個數字為1,2,3和4。
1 在數據量不大的情況下,排序
2 維護一個最小k 的數組 ,復雜度 為 o(k * N)
3 為一個最小K個數的最大堆 o(log2 k * N)
/* 查找最小的k 個元素 題目:輸入n 個整數,輸出其中最小的k 個。 例如輸入1,2,3,4,5,6,7和8這8個數字, 則最小的4個數字為1,2,3和4。 */ /* 思路 : 來一個數據處理一個 ,當來的數據量小于K 時 ,全部處理成最大堆, 然后之后來的,必須要小于最大堆的的最大值,才可以入堆,此時 只需更新 根節點,再調整堆。 */ # include<stdio.h> # include<stdlib.h> const int K = 5 ;//這里可以修改 const int MAXN = 1000; int max_heap[K+1] ;//維護一個 最大堆 int end ,maxPos; void swap(int &a ,int &b) { int t = a;a = b ; b = t; } int FindMax() { int maxPos = 1; for(int i = 2 ;i <= K ; i ++) if(max_heap[i] >max_heap[maxPos] ) maxPos = i; return maxPos; } /*將數據插入到 數組中 插入排序的思想*/ void insertMinHeap(int mdata) { int i,child = 0; if(end == K +1 ) // 如果堆滿 { /* int mmaxPos = FindMax();*/ if(mdata >= max_heap[1] ) // 如果大于等于該堆的最大值 不做任何改變 return ; max_heap[1] = mdata; for(i = 1 ; i*2 <= K ;i = child) { child = 2*i ; if((i*2 +1 <= K && max_heap[i*2] < max_heap[i*2+1]) )//返回最大孩子的下表 child ++; if(max_heap[i] < max_heap[child]) swap(max_heap[i] ,max_heap[child]); else { break; } } return ; } max_heap[end ++] = mdata; for(i = end -1 ; i > 1 ; i /=2) { if(max_heap[i] > max_heap[i/2]) swap(max_heap[i] ,max_heap[i/2]); else { break; } } } int main() { int n,data; freopen("in.txt","r",stdin);//如果想從文件輸入 將這句注釋掉 1234 1 2 3 4 5 6 7 8 9 10 11 end = 1; while(scanf("%d",&data)!=EOF) // 如果是手工輸入 結束輸入 按 ctrl + z { insertMinHeap(data); } for(int i = 1 ; i <= K ; i ++) // printf("%d ",max_heap[i]); printf("\n"); return 0; }