0.引言
基数排序,又称卡氏排序,源自于桶排序。
1.算法流程
自己定义的数据结构,不同于其他人的实现(用数组保存链表),自己改为了以链表保存链表。
整个链表的入口为总链RadioSortNode
,最后结果的输出从RadioSortNode
进去开始遍历各个子链就OK了.
2.代码实现
#include <iostream>
#include <algorithm>
using namespace std;
/*************************************基数排序radio sort***********************************/
/*************************************卡式排序bucket sort***********************************/
/*
1.将一组需要排序的数,用链表存储 记为 L
2.再用一组链表来存放分配的节点 N [0-9] ==>这里为了练习链表,我改了一下,将一组链改为了一链链.
3.遍历 L 每个节点分配到对应的 N [0-9]
4.将 N [0-9] 重新收集到 L
5.反复重复 3-4 直到最高位结束,排序结束,
6.L 就变成了有序
*/
#define NUM 10 //数个数
#define RADIX 10 //基数
#define POS_LEN 3 //位长
typedef struct RadioSortNode *PtrToRadioSortNode;
//链
struct RadioSortNode
{
int data;
PtrToRadioSortNode Next;
};
typedef PtrToRadioSortNode RadioSortNodeList;
typedef PtrToRadioSortNode RadioSortNodePosition;
//桶
typedef struct Bucket *PtrToBucket;
struct Bucket
{
RadioSortNodeList ChildBucket;//桶
int index;//桶的序号
PtrToBucket Next;
};
typedef PtrToBucket BucketList;
typedef PtrToBucket BucketPosition;
void InitRadioSortNodeListTail(RadioSortNodeList *L, const int A[])
{
RadioSortNodeList p, tail;
*L = (RadioSortNodeList)malloc(sizeof(Node));
(*L)->data = A[0];//不需要头结点
/* 如果定义了头结点,读取的时候
p = poly1->next; //指向第一个节点,跳过头结点
*/
tail = *L;//tail指向尾部的节点
for (int i = 1; i < NUM; i++)
{
p = (RadioSortNodeList)malloc(sizeof(RadioSortNode));//新节点
p->data = A[i];
tail->Next = p;//记住指针域里面只是一个数:地址,这里将当前节点的指针域更新
tail = p;//这里就将tail滑动到新节点,指针域此时是乱码
}
tail->Next = NULL;//记住最后一位的指针需要置为NUll
}
void InitBucketListTail(BucketList *L)
{
//总链
BucketList p, tail;
*L = (BucketList)malloc(sizeof(Bucket));
/*****子链******/
RadioSortNodeList childlist,p_childlist,tail_childlist;
childlist = (RadioSortNodeList)malloc(sizeof(RadioSortNode));
childlist->data = -1;
tail_childlist = childlist;
for (int i = 0; i < NUM; i++)
{
p_childlist = (RadioSortNodeList)malloc(sizeof(RadioSortNode));
p_childlist->data = -1;
tail_childlist->Next = p_childlist;
tail_childlist = p_childlist;
}
tail_childlist->Next = NULL;
//总链
(*L)->ChildBucket = childlist;
(*L)->index = 0;
tail = *L;
//free(childlist); free(p_childlist); free(tail_childlist);
for (int i = 1; i < NUM; i++)
{
//总链新节点
p = (BucketList)malloc(sizeof(Bucket));
/*****子链******/
RadioSortNodeList childlist, p_childlist, tail_childlist;
childlist = (RadioSortNodeList)malloc(sizeof(RadioSortNode));
childlist->data = -1;
tail_childlist = childlist;
for (int j = 0; j < NUM; j++)
{
p_childlist = (RadioSortNodeList)malloc(sizeof(RadioSortNode));
p_childlist->data = -1;
tail_childlist->Next = p_childlist;
tail_childlist = p_childlist;
}
tail_childlist->Next = NULL;
p->ChildBucket = childlist;
p->index = i;
//free(childlist); free(p_childlist); free(tail_childlist);
tail->Next = p;
tail = p;
}
tail->Next = NULL;
}
//显示Bucket List
void DisplayBucketList(BucketList *BL)
{
BucketList p;
p = *BL;
while (p->Next!=NULL)
{
cout << p->index << " : ";
RadioSortNodeList RL;
RL = p->ChildBucket;
while (RL->Next!=NULL)
{
cout << RL->data << " ";
RL = RL->Next;
}
cout <<endl;
p = p->Next;
}
cout << p->index << " : ";
RadioSortNodeList RL;
RL = p->ChildBucket;
while (RL->Next != NULL)
{
cout << RL->data << " ";
RL = RL->Next;
}
cout <<endl;
}
void DisplayList(RadioSortNodeList* L)
{
RadioSortNodeList p;
p = *L;
while (p->Next != NULL)
{
cout << p->data << " " ;
p = p->Next;
}
cout << p->data << " ";//最后一个没有输出
}
//取个十百位
int getListPos(int num, int position)
{
//int temp = 1, i;
//for (i = 0; i < N - 1; i++)
// temp *= RADIX;
cout << "getListPos:" << (num / temp) % RADIX << endl;
//return (num / temp) % RADIX;
//int tmp = 10 ^ N;
switch (position)
{
case 0: return num % 10;
case 1: return num / 10 % 10;
case 2: return num / 100 % 10;
case 3: return num / 1000 % 10;
case 4: return num / 10000 % 10;
default: break;
}
}
//找到桶位
BucketList FindBucketIndex(BucketList* BL,int idx)
{
BucketList bl;
bl = *BL;
while (bl->Next != NULL && bl->index != idx)
bl = bl->Next;
return bl;
}
//将排序的结果从桶拷贝回LIST
void BucketToRadioSortList(BucketList *BL,RadioSortNodeList *SL)
{
BucketList bl; bl = *BL;
RadioSortNodeList sl; sl = *SL;
while (bl->Next != NULL)
{
RadioSortNodeList RL;
RL = bl->ChildBucket;
while (RL->Next != NULL && RL->data!=-1)
{
sl->data = RL->data;
RL->data = -1;
RL = RL->Next;
sl = sl->Next;
}
bl = bl->Next;
}
RadioSortNodeList RL;
RL = bl->ChildBucket;
while (RL->Next != NULL && RL->data != -1)
{
sl->data = RL->data;
RL->data = -1;
RL = RL->Next;
sl = sl->Next;
}
}
void RadioSort(RadioSortNodeList *SL, BucketList *BL)//SL为待排序的链表,BL为桶链表
{
RadioSortNodeList sl;
BucketList bl,tmpbl;
sl = *SL;
bl = *BL;
int tmpdata;
for (int i = 0; i < POS_LEN; i++)
{
cout << endl << "第" << i+1 << "次排序" << endl;
sl = *SL;
while (sl->Next != NULL)
{
tmpdata = getListPos(sl->data, i);//获取个十百位
tmpbl = FindBucketIndex(&bl,tmpdata);
RadioSortNodeList RL;
RL = tmpbl->ChildBucket;
while (RL->Next != NULL && RL->data != -1)//如果里面有数据就挪动一位
RL = RL->Next;
RL->data = sl->data;//放入数据
sl = sl->Next;
}
//最后一位,这个问题要解决!!老是这样
tmpdata = getListPos(sl->data, i);//获取个十百位
tmpbl = FindBucketIndex(&bl, tmpdata);
RadioSortNodeList RL;
RL = tmpbl->ChildBucket;
while (RL->Next != NULL && RL->data != -1)//如果里面有数据就挪动一位
RL = RL->Next;
RL->data = sl->data;//放入数据
DisplayBucketList(BL);
BucketToRadioSortList(BL, SL);
cout << endl;
DisplayList(SL);
}
}
void RadioSortTest()
{
int A[] = { 0,1,8,512,216,125,27,729,343,64 };
//int N = sizeof(A) / sizeof(int);
//初始化桶
BucketList bucket;
InitBucketListTail(&bucket);
cout << "Init bucket with zero:"<<endl<<endl;
DisplayBucketList(&bucket);
cout << endl;
//初始化需要排序的链表
RadioSortNodeList sourcelist;
InitRadioSortNodeListTail(&sourcelist, A);
cout << "source of list:" << endl<<endl;
DisplayList(&sourcelist);
//排序
RadioSort(&sourcelist, &bucket);
}
int main(int argc, char** argv)
{
//StructPolynomialTest();
//ListPolynomialTest();
RadioSortTest();
//StudentCourseTest();
system("pause");
return 0;
}