排序算法之八 桶排序(C++版本)

一. 实现原理

桶排序的相关知识,参考漫画:什么是桶排序?

二. 具体实现

实现中,使用vector作为桶,只是从编码便利的角度出发。
因为需要对各个桶进行单独排序,所以,对桶进行的排序算法是否稳定,影响了整个算法的稳定性,这里使用的是sort算法,因此整个算法就是不稳定的。

void BucketSort(int* pData, int size)
{
	if (nullptr == pData || size <= 1) return;

	int minData = pData[0];
	int maxData = pData[0];
	for (int idx = 0; idx < size; ++idx)
	{
		if (pData[idx] < minData) minData = pData[idx];
		if (pData[idx] > maxData) maxData = pData[idx];
	}

	// 创建桶
	int bucketCount = (maxData - minData) / size + 1; // 桶数计算公式
	std::vector<std::vector<int>> buckets;

	// 向桶中插入数据
	for (int idx = 0; idx < size; ++idx)
	{
		int bucketIdx = (pData[idx] - minData) / size; // 桶下标计算公式
		buckets[bucketIdx].push_back(pData[idx]);
	}

	// 各个桶就行排序
	for (int idx = 0; idx < bucketCount; ++idx)
	{
		if (buckets[idx].empty()) continue;
		std::sort(buckets[idx].begin(), buckets[idx].end());
	}

	// 将桶中数据写回原数组
	for (int idx = 0, curIdx = 0; idx < bucketCount; ++idx)
	{
		auto& curBucket = buckets[idx];
		if (curBucket.empty()) continue;
		for (auto& curData : curBucket) pData[curIdx++] = curData;
	}
}

三. 输出验证

加上相关的输出信息后再进行调用。

辅助函数

void Print(int* pData, int size)
{
	for (int idx = 0; idx < size; ++idx) std::cout << pData[idx] << " ";
	std::cout << std::endl;
}

初始数据为

int datas[6] = { 1, 2, 3, 2, 1, 6 };

输出版本

void BucketSort_Output(int* pData, int size)
{
	if (nullptr == pData || size <= 1) return;

	std::cout << "INIT DATA" << std::endl;
	Print(pData, size);

	int minData = pData[0];
	int maxData = pData[0];
	for (int idx = 0; idx < size; ++idx)
	{
		if (pData[idx] < minData) minData = pData[idx];
		if (pData[idx] > maxData) maxData = pData[idx];
	}

	// 创建桶
	int bucketCount = (maxData - minData) / size + 1; // 桶数计算公式
	std::vector<std::vector<int>> buckets(bucketCount);

	// 向桶中插入数据
	for (int idx = 0; idx < size; ++idx)
	{
		int bucketIdx = (pData[idx] - minData) / size; // 桶下标计算公式
		buckets[bucketIdx].push_back(pData[idx]);
	}

	// 输出各桶中的数据
	for (int idx = 0; idx < bucketCount; ++idx)
	{
		std::cout << std::endl << "BUCKET " << idx << " DATA" << std::endl;
		Print(buckets[idx].data(), (int)buckets[idx].size());
	}

	// 各个桶进行排序
	for (int idx = 0; idx < bucketCount; ++idx)
	{
		if (buckets[idx].empty()) continue;
		std::sort(buckets[idx].begin(), buckets[idx].end());
		std::cout << std::endl << "SORT BUCKET " << idx << " DATA" << std::endl;
		Print(buckets[idx].data(), buckets[idx].size());
	}

	// 将桶中数据写回原数组
	for (int idx = 0, curIdx = 0; idx < bucketCount; ++idx)
	{
		auto& curBucket = buckets[idx];
		if (curBucket.empty()) continue;
		for (auto& curData : curBucket)
			pData[curIdx++] = curData;
	}

	std::cout << std::endl << "FINAL DATA" << std::endl;
	Print(pData, size);
}

调用输出

INIT DATA // 初始数据
1 2 3 2 1 6 10 20 30 15 18 60 55

BUCKET 0 DATA // 0号桶中数据
1 2 3 2 1 6 10

BUCKET 1 DATA// 1号桶中数据
20 15 18

BUCKET 2 DATA// 2号桶中数据
30

BUCKET 3 DATA// 3号桶中数据


BUCKET 4 DATA// 4号桶中数据
60 55

SORT BUCKET 0 DATA// 排序后0号桶中数据
1 1 2 2 3 6 10

SORT BUCKET 1 DATA// 排序后1号桶中数据
15 18 20

SORT BUCKET 2 DATA// 排序后2号桶中数据
30

SORT BUCKET 4 DATA// 排序后3号桶中数据
55 60

FINAL DATA // 最终数据
1 1 2 2 3 6 10 15 18 20 30 55s 60
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值