桶排序
桶排序的思想就是把區間[0,1)劃分爲n個相同大小的子區間,或稱桶。然後,將n個輸入輸出分佈到各個桶中去。因爲輸入樹均勻且獨立分佈且在[0,1)上,所以一般不會有很多數落在一個桶裏的情況。爲得到結果,先對各個桶裏的數進行排序,然後依次把各個桶中的元素列出來即可。
本版本的桶排序是利用雙鏈表實現。首先結構體定義如下:
struct Barrel_Node
{
float key;
int num;//記錄在原始s數組裏的下標
struct Barrel_Node *next;
struct Barrel_Node *pre;
};
通過動態內存分配,定義了以下幾個數組。注意Barrels定義到SIZE+1大小的桶,最大下標爲SIZE,因爲當s[i]=1.00時,k=s[i]*SIZE=SIZE,所以定義到SIZE+1是必要的。
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】
總的流程圖如下: