桶排序的定义
正如同他的名字一样“桶排序”,原理就是将数组分到有限数量的桶里。每个桶中的数据元素再进行排序(这里可以使用其他的排序方式或递归调用桶排序的方式进行排序,这里体现的是分而治之的思想)。最后再将桶内的元素输出得到一个排好的序列。
怎么实现桶排序呢?
- 设置一个数组来作为空桶
- 将所有的输入数据输入,将所有的数据传输到空桶内
- 在所有的桶中找到不为空的桶,将所有不为空的桶进行排序
- 将所有排好序的数取出连接起来
适用场景
排序一个班级学生的成绩 例如将学生的成绩以十分为梯度多段,即每以100为满分的情况下可以分为10个桶。将所有学生成绩输入到桶内,每一个桶进行桶内排序,最后将排好的名词输出。
通过上面这个例子,我们可以发现他的适用场景在数据分布相对比较均匀或者数据跨度范围并不是很大时效果比较好。我们在以后的使用过程中,除了对一些要求特别高并且数据分布较为均匀的情况使用桶排序,还是很少使用桶排序的,所以即使桶排序很简单、很快,我们也很少使用它。
排序特点
- 时间上:基数排序的速度是非常快的,甚至比快速排序还要快。
- 空间上:在把数据放入桶的过程中,由于事先不知道每个桶内到底要容纳多少个数据,也就无法准确确定大小。所以为了防止数组下标越界,就需要为每个桶开辟能够容纳整个数组的空间。实际上许多空间都是浪费了,这就是典型的利用空间换取时间上的效率。
时间复杂度
- 最优时间复杂度:o(n)
- 最坏时间复杂度:o(n^2)
- 稳定性:稳定
代码实现
java实现
import java.util.LinkedList;//
class bucket_sort {
int[] array;//要传入的排序数据
int[] buckets;//数组桶
public bucket_sort(int range, int[] array) {
//1.创建初始桶
this.buckets = new int[range];//创建桶
this.array = array;//传入数据
}
//2.传入数据
public void transer() {//将数据传入不同的桶
if (array != null && array.length > 1) {
for (int i = 0; i < array.length; i++) {
buckets[array[i]]++;
}
}
}
public void print() {
// 倒序输出数据
LinkedList list =new LinkedList();
for (int i = buckets.length - 1; i >= 0; i--) {
// 元素中值为几,说明有多少个相同值的元素,则输出几遍
for (int j = 0; j < buckets[i]; j++) {
list.add(i);
}
}
System.out.println(list);
}
public static class SortTest {
public static void main(String[] args) {
testBucketSort();
}
//桶排序
private static void testBucketSort() {
int[] array = {5, 9, 1, 9, 5, 3, 7, 6, 1};
bucket_sort bucketSort = new bucket_sort(11, array);
bucketSort.transer();
bucketSort.print();
}
}
}
c
#include <stdio.h>
#include <stdlib.h>
int main(){
int book[11];
int i,j,t,n;
for (int i = 0; i <=10 ; i++)
{
book[i]=0;//构造空桶
};
printf("请输入还有多少个数\n");
scanf("%d",&n);//输入数n表示接下来有多少个数
printf("请输入要排序的数\n");
for ( i = 1; i <=n ; i++) {
scanf("%d",&t);//将数读入变量t中
book[t]++;//计数
}
for (i=10; i>=0; i--) {
for ( j = 1; j<=book[i] ; j++) {
printf("%d",i);
}
}
system("pause");
}