博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序算法之——桶排序
阅读量:4616 次
发布时间:2019-06-09

本文共 1988 字,大约阅读时间需要 6 分钟。

这是本人的第一篇随笔,为的是分享学习经验,和大家讨论一些算法,以便取得些许进步,也是对学习的总结。

话不多说,下面我会用图文的方式向各位介绍桶排序。

1、主要思想:

  桶排序的大体思路就是先将数组分到有限个桶中,再对每个桶中的数据进行排序,可以说是鸽巢排序的一种归纳结果(对每个桶中数据的排序可以是桶排序的递归,或其他算法,在桶中数据较少的时候用插入排序最为理想)。

2、算法效率:

  对N个数据进行桶排序的时间复杂度分为两部分:

  1、对每一个数据进行映射函数的计算(映射函数确定了数据将被分到哪个桶),时间复杂度为O(N)。

  2、对桶内数据的排序,时间复杂度为∑ O(Ni*logNi) ,其中Ni 为第i个桶的数据量。

  对于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)。

  对于相同数量的数据,桶的数量越多,数据分散得越平均,桶排序的效率越高,可以说,桶排序的效率是空间的牺牲换来的。

3、算法分析:

初始化桶:

  桶排序中的桶其实是一组指向指针的指针,有点类似于哈希表中的链地址法,与之不同的是桶本身也是结构体(图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

 

4、代码展示(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);
        }    
    }
}

 

转载于:https://www.cnblogs.com/Unicron/p/9461075.html

你可能感兴趣的文章
ERP和C4C中的function location
查看>>
如何在SAP里创建configurable material物料主数据
查看>>
[转]C#设置WinForm快捷键
查看>>
中文版 R-FCN: Object Detection via Region-based Fully Convolutional Networks
查看>>
仿照支付宝账单界面--listview分组显示 用来做!发!财树充值交易明细
查看>>
java.lang.NoSuchMethodError:
查看>>
博客美化
查看>>
Appium下载和配置
查看>>
第三周总结
查看>>
cocos2dx plist
查看>>
python TCP时间戳服务器端、客户端
查看>>
JAVA输出带BOM的UTF-8编码的文件
查看>>
RDIFramework.NET 框架之组织机构权限设置
查看>>
XML简单介绍及举例
查看>>
eclips集成单元测试
查看>>
jquery事件使用方法总结 (转)
查看>>
js 内置对象
查看>>
Java 基础知识
查看>>
Android中两种获取并处理用户的截屏图片的方法
查看>>
基于虹软人脸识别Demo android人脸识别
查看>>