找出數組前N大的數


  這個題也是個比較有名的面試題.當然有很多變種.

  題目意思基本是:從一個數據量很大的數組里找前N大的元素.不允許排序.

  這個題有兩個比較好的思路:

  思路一:用快速排序的思想,是思想,不是要排序;

  思路二:用最大堆的思想.

  

  我暫時只實現了思路一,思路二我之后實現了會補上.

  

  思路一比較簡單了.我們先用快排的思想找出第n大的數,然后帶上后面n-1個就完事了.因為后面的都比支點數大.

  怎么找第n大的數?我在之前的博客寫過,請移步到  找第n大的數  

  

代碼:

#include<stdio.h>
#include<stdlib.h>

/*找出第n大的數的下標*/
int choose_nth(int a[], int startIndex, int endIndex, int n);

/*找出前n大的數*/
void choose_max_n(int a[],int startIndex, int endIndex, int n);

int main(int argc, char *argv)
{
    int a[] = {1,4,111,32,45,1000,99,300,8,22,189};
    int n,i;
    printf("數組是:\n");
    int an = sizeof(a)/sizeof(int);
    for(i = 0; i < an; ++i) 
        printf("%d ",a[i]);
    printf("\n");

    printf("你想找最大的前面幾個數:");
    scanf("%d",&n);
    
    choose_max_n(a, 0, an - 1, n);
    
    return 0;
}

void choose_max_n(int a[], int startIndex, int endIndex, int n)
{
    int i = choose_nth(a, startIndex, endIndex, n);
            
    printf("最大的前N個數是:\n");
    for(; i <= endIndex; ++i)
        printf("%d ",a[i]);
    printf("\n");
}


int choose_nth(int a[], int startIndex, int endIndex, int n)
{
    int midOne = a[startIndex];
    int i = startIndex, j = endIndex;
    if(i == j)
        return i;

    if(i < j)
    {
        while(i < j)
        {
            for(; i < j; j--)
            if(a[j] < midOne)
            {
                a[i++] = a[j];
                break;
            }

            for(; i < j; i++)
            if(a[i] > midOne)
            {
                a[j--] = a[i];
                break;
            }
        
        }

        a[i] = midOne;
        int th = endIndex - i + 1;

        if(th == n)
        {
            return i;    
        }
        else
        {
            if(th > n)
            {
                return choose_nth(a, i + 1, endIndex, n);
            }
            else
            {
                return choose_nth(a, startIndex, i - 1, n - th);            
            }
        }

    }
}

 

結果:

數組是:
1 4 111 32 45 1000 99 300 8 22 189 
你想找最大的前面幾個數:5
最大的前N個數是:
99 111 300 1000 189 

 

之后會補上用最大堆思想來做的代碼.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM