数据结构算法之基数排序(箱子排序的一种扩展)

15 篇文章 0 订阅
10 篇文章 1 订阅

数据结构算法之基数排序(箱子排序的一种扩展)

综述

关于基数排序是这样的:
1.我们类比箱子排序,基数排序就是对一串数字的的个位,十位,百位…进行分别排序,再将最终的排序结果输出,从而完成对整个一串数字的排序。这里基数排序是为了解决箱子排序的一些弊端:就比如数字范围过大,但是一串数字的个数较少。这样我们在初始化箱子的时候会浪费大量的空间和时间。所以我们用基数排序来减少初始化箱子所花费的时间。

2.因为每一个位上的数字是从0-9的所以我们对一个位数上的箱子进行初始化的时候,最多只需要初始化10个箱子。做多有n位的数字,就初始化10n个箱子,这样大大减少了我们初始化箱子所花费的时间。

3.我们要对那一个普通的节点进行扩展,在一个节点中,我们要存的不仅仅是next指针和element元素,还要存放一些运算的中间元素在节点中
(给出的代码中会有注释)

4.这个基数排序的方法使用的时候是有条件的,我们必须要知道所给的一串数字的大小范围,最大不超过多少。因为如果我们不知道数字串的大小范围的话,我们在寻找数字的最大位数的时候,会遇到很大的困难。从而,我们就无法建立相应合适的节点来储存数据。

步骤

下面我们来讲讲基数排序这个算法的步骤
第一步,我们先明确数字串的大小范围,是0-9999?还是0-999?还是0-99999?
第二步,我们构建节点,节点中存储一个next指针,一个element数据,同时还要存储一些运算时产生的中间变量。
第三步,我们构建chain类,将链表的头结点和链表长度设置好
第四步,我们实现节点和类中的所有成员函数
第五步,我们进入主函数,构建一个链表,并初始化(注意范围)
第六步。我们就直接调用排序函数佳宁排序操作。

代码展示

下面展示一些 内联代码片

#include<iostream>
using namespace std;
template<class T>
struct chainNode
{
	chainNode<T>* next;
	T element;
	//下面是一些中间变量保存在节点中
	T element1;
	T element2;
	T element3;
	T element4;
	T theUnit;//个位
	T theDecade;//十位
	T theHundred;//百位
	T theKilobit;//千位
	chainNode(){ }
	chainNode(chainNode<T>* next){this->next = next;}
	chainNode(chainNode<T>* next,T element){this->next = next;this->element = element;}
	chainNode(T element){this->element = element;} 
};
template<class T>
class chain
{
public:
	chain(int ListSize,chainNode<T>* FirstNode);
	chain(int initialCapacity = 10);
	void binSort(int range,int k);
	chainNode<T>* GetFirstNode();
private:
	int listSize;
	chainNode<T>* firstNode;
};
template<class T>
chainNode<T>* chain<T>::GetFirstNode()
{
	return firstNode;
}
template<class T>
chain<T>::chain(int ListSize,chainNode<T>* FirstNode)
{
	listSize = ListSize;
	firstNode = FirstNode;
}
template<class T>
chain<T>::chain(int initialCapacity)
{
	firstNode = NULL;
	listSize = 0;
}
template<class T>
void chain<T>::binSort(int range,int k)
{
	chainNode<T> **bottom,**top;
	bottom = new chainNode<T>*[range+1];
	top = new chainNode<T>* [range+1];
	for(int b=0; b<=range;b++)
	{
		bottom[b] = NULL;
	} 
	for(; firstNode != NULL; firstNode = firstNode->next)
	{
		int theBin;
		if(k == 0)  theBin = firstNode->theUnit;
		else if(k == 1)  theBin = firstNode->theDecade;
		else if(k == 2)  theBin = firstNode->theHundred;
		else if(k ==3)  theBin = firstNode->theKilobit;
		if(bottom[theBin] == NULL)
		{
			bottom[theBin] = top[theBin] = firstNode;
		}
		else 
		{
			top[theBin]->next = firstNode;
			top[theBin] = top[theBin]->next;
		}
	 } 
	 chainNode<T> *y = NULL;
	 for(int theBin = 0; theBin<range; theBin++)
	 {
	 	if(bottom[theBin] != NULL)
	 	{
	 		if(y == NULL)
			 {
			 	firstNode = bottom[theBin];
			 }
			 else 
			 {
			 	y->next = bottom[theBin];
			 }
			 y = top[theBin]; 
		}
	 }
	 if(y != NULL)
	 	y->next = NULL;
	 	
	delete []bottom;
	delete []top;
}
int main()
{
	chainNode<int>* head;
	chainNode<int>* q;
	head = new chainNode<int>;
	q = head;
	chain<int> List(10,head);
	cin >> head->element;
	for(int i = 0; i<10-1;i++)
	{
		q->next = new chainNode<int>;
		q = q->next;
		cin>>q->element;
	}
	q ->next = NULL;
	q = q->next;
	delete q;
	chainNode<int>* s = head;
	for(;s!=NULL;s = s->next)
	{
		cout<<s->element<<" ";
	}
	delete s;
	cout<<endl;
	chainNode<int>*i = head;
	int Max = 1;
	int MMax = 0;
	for(int h = 0;h<10;h++,i=i->next)
	{
		i->theUnit = i->element%10;
		i->element1 = i->element/10;
		if(i->element1 != 0)  Max++;
		
		i->theDecade = i->element1%10;
		i->element2 = i->element1/10;
		if(i->element2 != 0)  Max++;
		
		i->theHundred = i->element2%10;
		i->element3 = i->element2/10;
		if(i->element3 != 0)  Max++;
		
		i->theKilobit = i->element3%10;
		i->element4 = i->element3/10;
		if(i->element4 != 0)  Max++;
		
		if(Max>MMax) MMax=Max;
		Max = 1;
	}
	cout<<MMax<<endl;
	for(int i = 0;i<MMax;i++)
	{
		List.binSort(10,i);
	}
	//List.binSort(1000);
	chainNode<int>* b = List.GetFirstNode();
	for(;b!=NULL;b = b->next)
	{
		cout<<b->element<<" ";
	}
	delete b;
	return 0; 
		
}

后记

基数排序的算法很方便,但是具有一定的局限性,使用的时候要谨慎。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

元解~殇怀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值