桶排序
1. 过程与实质:
过程: 定义一个长度比最大输入值大的数组且该数组的每个元素都为零,将数组的每个元素看作铁桶,将输入的值看作旗子,然后对应该输入值的位置的数组元素自增一,当结束输入后,遍历整个数组便可以得到每个桶里的旗子数,即每个数值出现的次数。
经过这个过程以后,出现的数字对应的数组的元素便不再为0,没有出现的数字则还是0;
实质: 桶排序实质是将旗子插入桶里,以便统计旗子的个数的过程。
2. 优点
可以实现一边输入一边统计个数,不需要先排序统计个数,时间复杂度更低。
3. 解决问题
可以边遍历边统计,避免因为排序而超时的统计问题。
(名字为桶排序,但实际上是统计而不是排序)
4.代码
所输入的最大值比较小的情况
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int str[1000],i,n,x;
scanf("%d",&n);
for(i=0; i<1000; i++)//定义数组。
str[i]=0;
for(i=0; i<n; i++)//将旗子放入桶内。
{
scanf("%d",&x);
str[x]++;
}
for(i=0; i<n; i++)//统计每个桶里有多少旗子。
printf("%d ",str[i]);
return 0;
}
所输入的最大值比较大的情况
#include <iostream>
#include<algorithm>
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
int str[100000];
int main()
{
memset(str,0,100000);//定义一个每个元素全为0的数组。
//使用方法:memset(数组名称,定义每个元素的值,数组的个数)。
int x,i,n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&x);
str[x]++;
}
for(i=0;i<n;i++)
printf("%d ",str[i]);
return 0;
}
## 举例-QWQ和彩色石
-
题目介绍:
QWQ来到了一个神奇的地方,这个地方有很多颜色不同的彩色石,每个颜色都可以用一个数字来代替,QWQ收集了一堆石子,他想知道这堆石子中颜色相同的石子个数的最大值。 -
输入要求:
第1行输入一个数字n,代表这堆石子的个数,
第二行输入n个数,代表n个石子的颜色 ,
保证输入的所有数都不超过100。 -
输出要求:
输出一个数字,代表颜色相同的石子个数的最大值。 -
样例:
Input:
10
1 3 5 7 9 1 2 3 5 5
Output
3
5. 题解
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int str[105];
int main()
{
memset(str,0,105);
int n,x,i,maxx;
scanf("%d",&n);
maxx=0;
for(i=0; i<n; i++)
{
scanf("%d",&x);
str[x]++;
}
for(i=0; i<=n; i++)//对0到n进行遍历,以找到最大值;一定要到n不然出现极限情况则会遗漏!
{
if(str[i]>maxx)
{
maxx=str[i];
}
}
printf("%d",maxx);
return 0;
}
注释:
1.看到这里你一定会想到不用桶排序也可以解决这个问题的方法,但是如果最大值非常大达到1e5甚至以上呢,进行排序所消耗的时间是巨大的,有着大概率会超时的风险。
2.题目来自东北林业大学OJ网,题号:QWQ和彩色石;网址:acm.nefu.edu.cn。