桶排序 Bucket sort

本文深入探讨了桶排序的概念,包括它与基数排序的关系、使用映射函数进行划分的方法,以及桶排序的效率特点。文章还提供了一个以十位为标准的简单桶排序实现示例,帮助读者直观理解桶排序的原理。
桶排序在操作上类似于基数排序。
这是一种 分治/划分的思想。先定义一个“桶”,把数据集合分成若干个小集合。然后桶内的排序就是用普通的排序方法,选一个最优的。

划分的方法是需一个 映射函数f(k),将所有数据分别映射到各自的桶中。

基数排序的划分就是按照每个权值位的,桶排序也可以这样,但更好的情况是有一个能 类似hash的函数,能做到更好的映射。

效率:
平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。

其时间复杂度随着桶的数目增多而减小,最好的时间复杂度达到O(N)。极限情况是N个数据排序用N个桶,每桶只有1个数,这种情况就成了计数排序。

但是,桶排序不是原地的。由于桶是需要空间的,因此桶的数量越多,空间复杂度会增加。因此, 桶排序对数据的分布要求比较严苛。

另外,桶排序是 稳定的


桶排序的一种最简单的实现:以十位为标准进行划分,一共0-9十种桶。把原数据依次按划分标准放入对应的桶中。

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <malloc.h>  
  3. using namespace std;  
  4. typedef struct  node{  
  5.     int key;  
  6.     struct  node* next;  
  7. }keynode;  
  8.   
  9. void sort(int keys[], int size, int bucket_size)  
  10. {  
  11.     keynode **bucket_table = (keynode**)malloc(sizeof(keynode*)*bucket_size);  
  12.   
  13.     //init bucket  
  14.     for(int i=0;i<bucket_size;i++)  
  15.     {  
  16.         //桶内的首个结点记录着桶内的数据个数       
  17.         bucket_table[i] = (keynode*)malloc(sizeof(keynode));  
  18.         bucket_table[i]->key = 0;  
  19.         bucket_table[i]->next = NULL;  
  20.     }  
  21.   
  22.     //fill bucket  
  23.     for(int j=0;j<size;j++)  
  24.     {  
  25.         keynode *node = (keynode*)malloc(sizeof(keynode));  
  26.         node->key = keys[j];  
  27.         node->next = NULL;  
  28.   
  29.         //mapping function  
  30.         int index = keys[j]/10;  
  31.   
  32.         //桶内采用的是插入排序法  
  33.         keynode *p = bucket_table[index];  
  34.         p->key ++;  
  35.         if(p->key == 0)  
  36.         {  
  37.             p->next = node;  
  38.         }  
  39.         else  
  40.         {     
  41.             while(p->next != NULL && p->next->key <= node->key)  
  42.                 p = p->next;  
  43.             node->next = p->next;  
  44.             p->next = node;  
  45.         }  
  46.     }  
  47.     for(int b=0;b<bucket_size;b++)  
  48.         for(keynode *k=bucket_table[b]->next;k!=NULL;k=k->next)  
  49.             cout<<k->key<<" ";  
  50.     cout<<endl;  
  51. }  
  52.   
  53. int main()  
  54. {  
  55.     int data[] = {34,76,12,45,87,44,62,14};  
  56.     int size = sizeof(data)/sizeof(int);  
  57.     sort(data, size, 10);  
  58.     return 1;  
  59. }  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值