C++实现桶排序——十大经典排序算法之九【GIF动画+完整代码+详细注释】

十大经典排序算法系列博客——>传送门


桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

总结起来就是一句话:按值划分成多个区间, 每个区间排序, 最后合并。

算法步骤:

  • 设置一个定量的数组当作空桶;

  • 遍历输入数据,并且把数据一个一个放到对应的桶里去;

  • 对每个不是空的桶进行排序;

  • 从不是空的桶里把排好序的数据拼接起来。在这里插入图片描述

  • 动画演示

#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);
    
    return 0;
}

若要在桶排序的同时实现对数组的去重, 则用以下代码(将每个桶的容量看做1)

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    bool a[1005]={0};
    int c;
    int count=0;
    cin>>n;
    for(int i=0;i<n;i++)//输入数据,存放到数组对应的位置,表示该对应位置有数据了(而且还省了排序)
    {
        cin>>c;
        a[c]=1;
    }
    for(int i=0;i<1005;i++)//计算占了位置的数据有多少个,每个桶不管有几个相同数据,这里之后+1,所以可以说直接去重了
    {
       if(a[i]==1)
        count+=1;
    }
    cout<<count<<endl;
    for(int i=0;i<=1005;i++)//按顺序输出来
    {
        if(a[i]==1)
        cout<<i<<" ";
    }
    return 0;
}

日拱一卒,功不唐捐。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来老铁干了这碗代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值