排序算法之——桶排序

这是本人的第一篇随笔,为的是分享学习经验,和你们讨论一些算法,以便取得些许进步,也是对学习的总结。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);        }        }}
相关文章
相关标签/搜索