综述
关于基数排序是这样的:
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;
}
后记
基数排序的算法很方便,但是具有一定的局限性,使用的时候要谨慎。