桶排序

桶排序

        桶排序的思想就是把區間[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】

總的流程圖如下:

《桶排序》

《桶排序》

《桶排序》

《桶排序》

点赞