查找最小的k個元素(數組)

 

題目:輸入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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章