C++基数排序

8 篇文章 1 订阅
3 篇文章 0 订阅

目录

 

一、概述

二、代码

三、程序运行情况


一、概述

1、基本思想(沿袭自桶排序):

从低位开始,对所有数字进行排序。例如第1轮排序后,数字的个位数要有序;第2轮排序后,数字的十位数要有序,如果十位数相同的数,个位数要按照之前的相对顺序摆放;依次类推直至最高位排序完成。过程如下图:

二、代码

C++利用vector实现

/*======================================================
*
*程序说明:	C++基数排序实现
*运行平台:	Linux/Windows
*创建日期:	20190831
*作	  者:	LiuHuan
*
*======================================================*/

#include <iostream>
#include <vector>
#include <time.h>	// 随机数种子
#include <chrono>	// 统计运行时间需要

using namespace std;
using namespace chrono;

#define RUN_SORT(FUNC)	\
{	\
	auto tStart = system_clock::now();	\
	FUNC;	\
	auto tEnd = system_clock::now();	\
	auto tCost = duration_cast<nanoseconds>(tEnd - tStart);	\
	cout << "耗时: " << tCost.count() << " ns(纳秒).\n" << endl;	\
}

// 随即返回正负
int Symbol(int num)
{
	return (num == 1 ? 1 : -1);
}

void CardinalitySort(vector<int>& vec)
{	
	// 1、确定最大值
	int maxValue = vec[0];	
	for (auto it : vec)
	{
		maxValue = maxValue >= it ? maxValue : it;	
	}

	// 2、确定最大值位数
	int maxNumLength = 0;
	for (int i = maxValue; i != 0; i /= 10)
	{
		maxNumLength++;
	}

	// 3、借用桶排序思想
	int mod = 10, dev = 1;
	// 根据最大位数, 就有几轮建桶过程, 依次从个位到最高位建桶
	for (size_t i = 0; i < maxNumLength; i++, dev *= 10, mod *= 10)
	{
		vector<vector<int> > vecBucket;		// 该轮的桶
		// 桶初始化, 只需要十个桶(根据该位“数值”入0 - 9号桶)
		// 若还需考虑负值, 桶个数扩大一倍(20个桶), 前0-9存取负数, 后10-19存取正数
		for (size_t i = 0; i < 20; i++)
		{
			vector<int> vecTmp;
			vecBucket.push_back(vecTmp);
		}

		// 数据入桶
		for (size_t j = 0; j < vec.size(); j++)
		{
			int bucketIndex = ((vec[j] % mod) / dev) + 10;	// 该位数值即为该入的桶编号
			vecBucket[bucketIndex].push_back(vec[j]);
		}

		vec.clear();
		for (auto itBucket : vecBucket)
		{
			for (auto itNum : itBucket)	// 注意itBucket也是一个vector
			{
				vec.push_back(itNum);
			}
		}
	}
}

template<typename T>
void printVec(const vector<T>& vec)
{
	int cnt = 1;
	for (auto it : vec)
	{
		cout << it << "\t";
		if (cnt++ % 10 == 0)	// 每十个换行输出
		{
			cout << "\n";
		}
	}
	cout << "\n\n";
}

int main()
{
	srand((unsigned int)time(NULL));
	int cnt = 1;
	do
	{
		vector<int> vec;
		for (size_t i = 0; i < 10; i++)		// 注意这里元素值和序列大小的选取对排序性能有影响,建议读者自己改变参数调试, 研究一番
		{
			int value = Symbol(rand() % 2) * rand() % 1000;
			vec.push_back(value);
		}
		cout << "************第[ " << cnt << " ]次基数排序前序列:\n";
		printVec(vec);

		RUN_SORT(CardinalitySort(vec))

		cout << "基数排序后序列:\n";
		printVec(vec);

	} while (cnt++ < 5);

	//system("pause");  // linux关闭,VS打开
	return 0;
}

 

三、程序运行情况

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幻欢子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值