• [算法]统计排序(桶排序)


    看了一道笔试题,说有100W个数据,范围在0~65535之间,要求用最少的空间和最快的速度进行排序。

    刚开始的思路是,65535就是2^16,那首先要把数据类型定义为short。其次,要用最少的空间,那最好还是不用递归,那不用快排。不递归,速度又快,那肯定是堆排序了。O(n)的空间+O(nlogn)的时间。

    后来看了网上的人对于这题的评点,原来统计排序才是这一条件下的最优解。

    统计排序,又叫桶排序。它的原理非常简单。在知道数据大小范围的条件下,定义一个等于数据大小范围的数组。数组初始化为0,然后直接用数据作为数组下标统计数据个数,最后把统计数据从头到尾输出(升序),或者从尾到头输出(降序)即可。时间复杂度为O(N)。

    因此,当题目有以下特点时,考虑统计排序:1、数据范围确定 2、数据范围小于数据个数

    考虑题目条件,2^16 < 100W=2^20 < 2^32 (unsigned int范围),因此定义一个长为65535的数组做统计。

    unsigned short value;
    unsigned int array[65536];
     
    memset(array, 0, sizeof(array));
    while (get_value(&value)) {
        ++array[value];
    }

    有的题目可能没有明确给出数据的范围,但其实已经隐含给出了。例如:给出一个包含数字与字母的字符串,要求字母位置不变,对数字排序。题目隐含了数字的大小是0~9,因此使用统计排序做就非常简单了。

    void sortstr( char *str){
        cout<<str<<endl;
        int count[10]={0};
        int j=0;
        while(str[j]!=''){
            if(str[j]>='0' && str[j]<='9'){
                count[str[j]-'0']++;
            }
            j++;
        }
        j=0;
        int i=0;
        while(str[j]!=''){
            if(str[j]>='0' && str[j]<='9'){
                while(count[i]==0 && i<10){
                    i++;
                }
                if(i<10){
                    str[j]=i+'0';
                    count[i]--;
                }
            }
            j++;
        }
        cout<<str<<endl;
    }

     

  • 相关阅读:
    属性MyBank
    C#语法
    NTE与C#
    css3制作网页动画
    网页定位元素
    使用ADO.NET访问数据库
    连接查询和分组查询
    模糊查询和聚合函数
    习题集
    用sql语句操作数据
  • 原文地址:https://www.cnblogs.com/iyjhabc/p/3316253.html
Copyright © 2020-2023  润新知