找出数组前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 

 

之后会补上用最大堆思想来做的代码.

 

posted @ 2014-12-03 20:40  开开甲  阅读(3370)  评论(0编辑  收藏  举报