- 基本思想
桶排序的思想是,若待排序的记录的关键字在一个明显有限范围内时,可设计有限个有序桶,每个桶只能装与之对应的值,顺序输出各桶的值,将得到有序的序列。简单来说,在我们可以确定需要排列的数组的范围时,可以生成该数值范围内有限个桶去对应数组中的数,然后我们将扫描的数值放入匹配的桶里的行为,可以看作是分类,在分类完成后,我们需要依次按照桶的顺序输出桶内存放的数值,这样就完成了桶排序。
例如,要求我们输入 n 个 0~9 之间的整数,由小到大排序输出,我们可以准备 10 个桶依次编号为 0~9。那么,输入的数 0 则入 0 号桶,1 入 1 号桶,依次类推。
a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | a[8] | a[9] | a[10] | a[11] |
6 | 9 | 2 | 4 | 1 | 5 | 3 | 7 | 10 | 8 | 1 |
把b数组的值用来统计a数组中的值出现的次数 a数组的值用来充当b数组的下标 |
||||||||||
b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] | b[10] | |
2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
这个算法就好比有 11 个桶,编号从 0~10。每出现一个数,就将对应编号的桶中的放一个小旗子,最后只要数数每个桶中有几个小旗子就 OK 了、
现在你可以请尝试一下输入 n 个 0~10之间的整数,将他们从大到小排序。提醒一下如果需要对数据范围在 0~10 之间的整数进行排序,我们需要 11 个桶,来表示 0~10 之间每一个数出现的次数,这一点一定要注意。另外此处的每一个桶的作用其实就是“标记”每个数出现的次数,因此我喜欢将之前的数组 a 换个更贴切的名字 book(book 这个单词有记录、标记的意思),代码实现如下。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int book[11],t,n;
for(int i=0;i<=10 ;i++)
book[i]=0;
cin>>n;//输入一个数n,表示接下来有n个数
for(int i=1;i<=n;i++)//循环读入n个数,并进行桶排序
{
cin>>t; //把每一个数读到变量t中
book[t]++; //进行计数,对编号为t的桶放一个小旗子
}
for(int i=10 ;i>=0;i--)
//依次判断编号10 ~0的桶,从大到小打印
for(int j=1;j<=book[i];j++) //出现了几次就将桶的编号打印几次
cout<<i<<" ";
return 0;
}
只需要将for(i=10;i>=0;i--)改为 for(i=0;i<=10;i++) 就是从小到大
时间复杂度是 o(n)