桶排序
桶排序的思想就是把区间[0,1)划分为n个相同大小的子区间,或称桶。然后,将n个输入输出分布到各个桶中去。因为输入树均匀且独立分布且在[0,1)上,所以一般不会有很多数落在一个桶里的情况。为得到结果,先对各个桶里的数进行排序,然后依次把各个桶中的元素列出来即可。
本版本的桶排序是利用双链表实现。首先结构体定义如下:
struct Barrel_Node
{
float key;
int num;//记录在原始s数组里的下标
struct Barrel_Node *next;
struct Barrel_Node *pre;
};
static int Barrels_count[SIZE+1];//每个数组的元素记录了对应Barrels里已经放入的数的个数
struct Barrel_Node *Barrels = (struct Barrel_Node*)malloc(sizeof(struct Barrel_Node)*(SIZE+1)); //桶
struct Barrel_Node *Barrels_tmp = (struct Barrel_Node*)malloc(sizeof(struct Barrel_Node)*(SIZE+1)); //用来存放第2,第3,....个结点,然后放到对应的桶
int Barrels_tmp_count = 0;//指向当前可用的Barrels_tmp结点
基本的思想是:
for i ← 0 to SIZE
k = s[i]*SIZE
if Barrels_count[k] = 0
then do 【case1】
else //【case2】桶里非空
Barrels_tmp[Barrels_tmp_count].key = s[i] //在Barrels_tmp里取一个来装key
Barrels_tmp[Barrels_tmp_count].num = i
Barrels_tmp[Barrels_tmp_count].next = NULL
p = &Barrels[k]
while (p->next != NULL) //找合适的,即插入点的pre结点
p = p->next
p->next = &Barrels_tmp[Barrels_tmp_count] //加入链表,放入桶里
Barrels_tmp[Barrels_tmp_count].pre = p
if s[i] < p->key //【case2.1】如果s[i]比p的值小,那么就需要调整
if s[i] <= Barrels[k].key //【case2.1.1】如果s[i]不大于第一个数,那么可以把s[i]当初首元素
then do 【case2.1.1】
else //【case2.1.2】s[i]大于第一个数
then do 【case2.1.2】
else //【case2.2】s[i]大于p的值,那么只需要将s[i]接到链表的最后即可
then do 【case2.2】
总的流程图如下: