[算法]统计排序(桶排序)
2013-09-12 10:15
232 查看
看了一道笔试题,说有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的数组做统计。
有的题目可能没有明确给出数据的范围,但其实已经隐含给出了。例如:给出一个包含数字与字母的字符串,要求字母位置不变,对数字排序。题目隐含了数字的大小是0~9,因此使用统计排序做就非常简单了。
刚开始的思路是,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]!='\0'){ if(str[j]>='0' && str[j]<='9'){ count[str[j]-'0']++; } j++; } j=0; int i=0; while(str[j]!='\0'){ 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; }
相关文章推荐
- C 语言 简单桶排序 算法&实现
- 【啊哈!算法】最快最简单的排序——桶排序
- 【啊哈!算法】最快最简单的排序――桶排序
- 【啊哈!算法】最快最简单的排序——桶排序
- 【啊哈!算法】最快最简单的排序——桶排序 推荐
- 简单的桶排序(个人练习算法)
- 【一周一算法】算法1:最快最简单的排序——桶排序(转)
- [C语言算法]排序之桶排序
- 【算法导论】线性时间排序-计数排序、基数排序及桶排序
- 排序算法---基础算法(冒泡排序,快速排序,选择排序,直接插入排序,桶排序)
- 算法是个什么玩意儿-桶排序和鸽巢排序
- 常用算法--基本排序算法(冒泡排序,选择排序,插入排序,快速排序,归并排序,桶排序)
- 【算法学习】线性时间排序-计数排序、基数排序和桶排序详解与编程实现
- 算法 - 桶排序(简化版)
- 桶排序、冒泡排序、快速排序 -- 算法学习 小结篇
- 算法导论之桶排序
- [笔记]算法复习笔记---排序算法(桶排序、冒泡排序)
- C++学习笔记 —— 算法 —— 桶排序
- 算法:桶排序
- 桶排序 - 算法 - Scala版