原理
- :按照需要排序数组的实际情况,生成一个一定长度的一维数组,用于统计需要排序数组的不同数值的重复次数,完成统计后,再按顺序重复输出该数值
- 🤔再简单点说
桶排序的基本思想是假设数据在[min,max]之间均匀分布,其中min、max分别指数据中的最小值和最大值。那么将区间[min,max]等分成n份,这n个区间便称为n个桶。将数据加入对应的桶中,然后每个桶内单独排序。由于桶之间有大小关系,因此可以从大到小(或从小到大)将桶中元素放入到数组中。
简单说,你有一个数组1 , 3 , 7 , 77 ,100 ,234
比如,
你把一位数、两位数和三位数分到3个桶里,
各自排完序再合到一起
排序前:1 , 3 , 7 , 77 ,100 ,234
一位数:1、7、3
两位数:77
三位数:100、234
排序后:
一位数:1、3、7
两位数:77
三位数:100、234
合起来:1、3、7、77、100、234
思路
1.设置一个定量的数组当作空桶子。
2.寻访序列,并且把项目一个一个放到对应的桶子去。
3.对每个非空的桶子进行排序。
4.从不是空的桶子里把项目再放回原来的序列中。
代码
#include <bits/stdc++.h>
using namespace std;
// 打印数组
void print_array(int *arr, int n) {
if(n==0){
printf("ERROR: Array length is ZERO\n");
return;
}
printf("%d", arr[0]);
for (int i=1; i<n; i++)
printf(" %d", arr[i]);
printf("\n");
}
int* sort_array(int *arr, int n) {
int i;
int maxValue = arr[0];
for (i = 1; i < n; i++)
if (arr[i] > maxValue) // 输入数据的最大值
maxValue = arr[i];
// 设置10个桶,依次0,1,,,9
const int bucketCnt = 10;
vector<int> buckets[bucketCnt];
// 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
// 最大值999,桶大小100
// 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
int bucketSize = 1;
while (maxValue) { //求最大尺寸
maxValue /= 10;
bucketSize *= 10;
}
bucketSize /= 10; //桶的个数
// 入桶
for (int i=0; i<n; i++) {
int idx = arr[i]/bucketSize; //放入对应的桶
buckets[idx].push_back(arr[i]);
// 对该桶使用插入排序(因为数据过少,插入排序即可),维持该桶的有序性
for (int j=int(buckets[idx].size())-1; j>0; j--) {
if (buckets[idx][j]<buckets[idx][j-1]) {
swap(buckets[idx][j], buckets[idx][j-1]);
}
}
}
// 顺序访问桶,得到有序数组
for (int i=0, k=0; i<bucketCnt; i++) {
for (int j=0; j<int(buckets[i].size()); j++) {
arr[k++] = buckets[i][j];
}
}
return arr;
}
int main() {
int n;
scanf("%d", &n);
int *arr;
arr = (int*)malloc(sizeof(int)*n);
for (int i=0; i<n; i++) scanf("%d", &arr[i]);
arr = sort_array(arr, n);
print_array(arr, n);
system("pause");
return 0;
}