排序算法之——桶排序

這是本人的第一篇隨筆,爲的是分享學習經驗,和你們討論一些算法,以便取得些許進步,也是對學習的總結。node

話很少說,下面我會用圖文的方式向各位介紹桶排序。算法

一、主要思想:數組

  桶排序的大致思路就是先將數組分到有限個桶中,再對每一個桶中的數據進行排序,能夠說是鴿巢排序的一種概括結果(對每一個桶中數據的排序能夠是桶排序的遞歸,或其餘算法,在桶中數據較少的時候用插入排序最爲理想)。
函數

二、算法效率:學習

  對N個數據進行桶排序的時間複雜度分爲兩部分:spa

  一、對每個數據進行映射函數的計算(映射函數肯定了數據將被分到哪一個桶),時間複雜度爲O(N)。指針

  二、對桶內數據的排序,時間複雜度爲∑ O(Ni*logNi) ,其中Ni 爲第i個桶的數據量。code

  對於N個待排數據,M個桶,平均每一個桶[N/M]個數據的桶排序平均時間複雜度爲:O(N)+O(M*(N/M)*log(N/M))=O(N+N*(logN-logM))=O(N+N*logN-N*logM),當N=M時,即極限狀況下每一個桶只有一個數據時。桶排序的最好效率可以達到O(N)。blog

  對於相同數量的數據,桶的數量越多,數據分散得越平均,桶排序的效率越高,能夠說,桶排序的效率是空間的犧牲換來的。排序

三、算法分析:

初始化桶:

  桶排序中的桶實際上是一組指向指針的指針,有點相似於哈希表中的鏈地址法,與之不一樣的是桶自己也是結構體(圖1是鏈地址法,圖2爲初始化後的桶)

  

②將數據放入相應的桶的同時對該桶排序:

  遍歷數據,根據映射函數對數據進行計算,下圖的映射函數爲N/10(N是當前數據),肯定了桶以後,將數據在桶中採用直接插入法。下圖爲對數組a的桶排序。

說明

 (圖中key是桶中數據個數)

  

  以25和23爲例,25/10=2,肯定25的位置在第二個桶,此時桶2尚未元素,因此直接插入,23/10=2,肯定在第二個桶,此時桶2的key不爲0,23<25將23插入25以前,其餘的相似。

 

③按按照桶的順序將元素輸出:

  按上圖中的狀況,排序後的順序就爲:10 23 25 26 30 41 43

 

四、代碼展現(C語言):

#include<stdio.h>#include<stdlib.h>typedef struct node{    int key;    struct node* next;}KeyNode;void bucket_sort(int keys[],int size,int bucket_size);int main(){    int a[]={11,11,9,21,14,55,77,99,53,25};    int size=sizeof(a)/sizeof(a[0]);    bucket_sort(a,size,10);    return 0;}void bucket_sort(int keys[],int size,int bucket_size){    KeyNode **bucket_table=(KeyNode**)malloc(bucket_size*sizeof(KeyNode*));    for(int i=0;i<bucket_size;i++){    //初始化桶         bucket_table[i]=(KeyNode*)malloc(sizeof(KeyNode));        bucket_table[i]->key=0;        bucket_table[i]->next=NULL;    }    for(int i=0;i<size;i++){        KeyNode* node=(KeyNode*)malloc(sizeof(KeyNode));        node->key=keys[i];        node->next=NULL;        int index=keys[i]/10;//給數據分類的方法(關係到排序速度,很重要)        KeyNode *p=bucket_table[index];        if(p->key==0){            p->next=node;            p->key++;        }                    else{            while(p->next!=NULL&&p->next->key<=node->key){//=的時候後來的元素會排在後面                 p=p->next;            }            node->next=p->next;            p->next=node;            (bucket_table[index]->key)++;        }    }    KeyNode* k=NULL;    for(int i=0;i<bucket_size;i++){        for(k=bucket_table[i]->next;k!=NULL;k=k->next){            printf("%d ",k->key);        }        }}
相關文章
相關標籤/搜索