題目:輸入n個整數(shù),輸出其中最小的k個。
例如輸入1,2,3,4,5,6,7和8這8個數(shù)字,則最小的4個數(shù)字為1,2,3和4。
1 在數(shù)據(jù)量不大的情況下,排序
2 維護(hù)一個最小k 的數(shù)組 ,復(fù)雜度 為 o(k * N)
3 為一個最小K個數(shù)的最大堆 o(log2 k * N)
/*
查找最小的k 個元素
題目:輸入n 個整數(shù),輸出其中最小的k 個。
例如輸入1,2,3,4,5,6,7和8這8個數(shù)字,
則最小的4個數(shù)字為1,2,3和4。
*/
/*
思路 : 來一個數(shù)據(jù)處理一個 ,當(dāng)來的數(shù)據(jù)量小于K 時 ,全部處理成最大堆,
然后之后來的,必須要小于最大堆的的最大值,才可以入堆,此時 只需更新 根節(jié)點,再調(diào)整堆。
*/
# include<stdio.h>
# include<stdlib.h>
const int K = 5 ;//這里可以修改
const int MAXN = 1000;
int max_heap[K+1] ;//維護(hù)一個 最大堆
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;
}
/*將數(shù)據(jù)插入到 數(shù)組中 插入排序的思想*/
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) // 如果是手工輸入 結(jié)束輸入 按 ctrl + z
{
insertMinHeap(data);
}
for(int i = 1 ; i <= K ; i ++) //
printf("%d ",max_heap[i]);
printf("\n");
return 0;
}
posted on 2011-04-21 13:26
付翔 閱讀(1292)
評論(0) 編輯 收藏 引用 所屬分類:
ACM 數(shù)據(jù)結(jié)構(gòu)