标签:
桶排序,顾名思义,为要拍排序数组分配一些的”桶“来排序,什么意思呢?假如你有一个数组,其中包含10个元素,其中最大的数字是90,你就分配个90个以上的桶(假如定义一个int a[101]),你可以看到,10个数定义一个含100个元素的数组用来排序(当然,a[100]随便啦,你定义int a[100],a[193]都可以,只要这个元素的个数多于要排序数组的最大数,这都是你估计的,所以你尽量数组往大里面定义,原因你看排序过程即可),很费空间,但是很省时间。下面说一个排序过程。
假如你第一个数字是3,我们就将对应的a[3]加一,表示3出现了一次;第二个数假如是45,我们将对应的a[45]加一,表示45出现了一次,以此类推。不知道你发现没有,a[0]-a[100]就是数组中每个数出现的次数。完成这些以后,在a[101]中打印那些不是0的数字就好了~看代码试试能不能看明白。
#include <iostream> using namespace std; int main() { int a[101]={0}; int t=0; for(int i=0;i<10;i++) { cin>>t; a[t]++; } for(int i=100;i>=0;i--) for(int j=0;j<a[i];j++) cout<<i<<‘\t‘; return 0; }
事实上,十分简单,不是吗?
我看见过一个面试题,和桶排序相当类似,转载一下。地址是:http://www.cnblogs.com/edisonchou/p/4808816.html
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出‘b‘。要求时间复杂度为O(n)。
复杂度为O(n),所以两重循环这种思路行不通了,只能空间换时间。
思路(转载自上面的网页):
(1)第一次扫描字符串时,每扫描到一个字符就在哈希表的对应项中把次数加1。(时间效率O(n))
(2)第二次扫描时,每扫描到一个字符就能从哈希表中得到该字符出现的次数。这样第一个只出现一次的字符就是符合要求的输出。(时间效率O(n))
#include <iostream> using namespace std; char FirstRepresenting(char *p,int length) { const int size=256;//之所以初始化为256,见下面的PS int Table[size]={0}; char a[length]; for(int i=0;i<length;i++) a[i]=0; int i=0; while(*p) { a[i++]=*p++; } for(int i=0;i<length;i++) Table[a[i]]++; for(int i=0;i<size;i++) { if(Table[a[i]]==1) { return a[i]; } } return ‘\0‘; } int main() { char a[10]={0}; cin>>a; char b=FirstRepresenting(a,10); cout<<b; return 0; }
PS:字符(char)是一个长度为8的数据类型,因此总共有256种可能。(在C#中char则是长度为16位也就是2个字节)这里我们只列举char是1个字节的情况,我们创建一个长度为256的数组来模拟哈希表,每个字母根据其ASCII码值作为数组的下标对应数组的一个数字,而数组中存储的是每个字符出现的次数。计算下来,它的大小是256*4字节(1个int类型在Windows下占4个字节)=1K。由于这个数组的大小是个常数,因此可以认为这种算法的空间复杂度是O(1)。
看~是不是很像桶排序?
完
标签:
原文地址:http://www.cnblogs.com/mengnan/p/4890338.html