排序算法:桶排序

一 、介绍:什么是桶排序?

桶排序是在已经数据的范围的条件下,创建若干个桶,根据相应的比较规则将待排数据落入各个对应的桶中,最后扫描桶来实现排序。
其思想是:若干元素分布在某个区间[a,b],则将该区间划分为n个大小相同的子区间,使每一个元素都均匀且独立的分布在某个子区间上。我们把这n个子区间称为桶,再对每个桶进行桶内排序,最后依次合并每一个桶。

二 、基本步骤

将原数组所属区间均分为若干子区间,即建立若干个桶;
遍历原数组,并将数据放入到各自对应的桶中;
对每一个非空的桶进行排序;
依次合并每一个桶,即将其按顺序放入原数组中,最后即可得到一个排好序的新数组。

三 、应用示例

1 、将20个0~100范围内的整数排序。


排序流程大致如图(PS:图片摘自网络,原图地址:http://www.myexception.cn/program/1668221.html

我的代码如下:

#include<bits/stdc++.h>
using namespace std;
vector<int>bucket[10];//由于数据范围为0~100,不妨根据其十位数大小划分10个桶 (100即放在“10”这个桶) 
int a[50];
int n,t=0;
int index(int v)//确定每个元素所在的“桶 ” 
{
    return v/10;
}
void bucket_sort(int a[])
{
    for(int i=1;i<=n;i++)   
        {
           int m=index(a[i]);       
           bucket[m].push_back(a[i]);//将原数组中每个元素放入对应的桶      
        }
    for(int i=0;i<=10;i++)    
        {
            sort(bucket[i].begin(),bucket[i].end());//桶内排序,也可以使用其他排序方法(比如插入排序) 
            int len=bucket[i].size()-1;
            for(int j=0;j<=len;j++)//合并桶,将每一个桶内的元素放回原桶 
                {
                    t++;
                    a[t]=bucket[i][j];
                }
        }
}
int main()
{
    scanf("%d",&n);//输入排序数据个数 
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]); 
    bucket_sort(a);    //排序 
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);//打印结果 
    return 0;
}

可以输入一下数据进行验证:

20
8 4 2 69 47 32 85 66 98 85 74 15 87 45 25 78 62 34 0 100

四 、基于计数排序的简化版本

基本思路与原来大致一致,只不过划分桶时,每一个单位就划分一个桶,将每一个元素装入对应的桶。(就是在0~最大值范围内,每个数都有一个桶)注意!此时桶里装的并非元素本身,而是该元素的出现次数。最后合并桶即可。

例:对十个数据进行排序

我的代码如下:

#include<bits/stdc++.h>
using namespace std;
int bucket[500];
int a[50]; 
int n,maxn=0;
void bucket_sort(int a[])
{
    int t=0;
    for(int i=0;i<=maxn;i++)
        bucket[i]=0;//清空桶 
    for(int i=1;i<=n;i++)
        bucket[a[i]]++; //统计每个元素的出现次数 
    for(int i=0;i<=maxn;i++)//合并桶,将其放回原数组中 
        for(int j=1;j<=bucket[i];j++)
            {
                t++;
                a[t]=i;
            }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(maxn<a[i])//找出最大值 
               maxn=a[i];
        }
    bucket_sort(a);//排序 
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);//打印结果 
    return 0;
}

可输入如下数据进行验证:

10
4 5 2 4 3 9 7 23 5 8

五 、桶排序优缺点分析

1 、优点:
桶排序的时间复杂度为O(n+c)(c为桶内排序所使用的排序方式的复杂度),而当桶越多,其时间效率就越高,利用桶排序,可以实现线性的时间复杂度!
此外,桶排序是稳定的
2 、缺点
桶排序的缺点很明显,就是太耗空间了。桶越多,空间复杂度就越高(这也算是以空间换时间了吧……然而在NOIP范围内,空间什么的就是随便浪费的!)
3 、使用范围
1.处理数据非负(当然也不是不可以处理负数,但比较麻烦)
2.数据较为集中不能太分散

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值