zoukankan      html  css  js  c++  java
  • 找出数组前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("数组是:
    ");
        int an = sizeof(a)/sizeof(int);
        for(i = 0; i < an; ++i) 
            printf("%d ",a[i]);
        printf("
    ");
    
        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个数是:
    ");
        for(; i <= endIndex; ++i)
            printf("%d ",a[i]);
        printf("
    ");
    }
    
    
    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 

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

  • 相关阅读:
    CentOS配置bond
    rsync 06-sersync文件实时同步
    rsync 07-confxml.xml配置文件
    rsync 04-rsyncd启动脚本
    rsync 03-rsyncd.conf配置文件
    rsync 01-rsync命令使用
    rsync 02-部署rsync的daemon模式
    CentOS7升级OpenSSH
    iptables 02-CentOS7.x 启用iptables
    iptables 01-iptables命令
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/4141184.html
Copyright © 2011-2022 走看看