桶排序(Bucket Sort)
2017-01-17 12:48
369 查看
桶排序(Bucket Sort)
桶排序Bucket Sort基本思想
排序流程
算法实现
算法分析
1. 基本思想
简单来说,就是把数据分组,放在一个个的桶中,然后对每个桶里面的再进行排序。步骤
划分桶
入桶
桶内排序
出桶
2. 排序流程
例如对[0, 40]范围内的n个整数A[1..n]排序 。首先,可以把桶设为大小为10的范围,具体而言,设集合B[1]存储[0, 10)的整数,集合B[2]存储[10, 20)的整数,……集合B[i]存储[(i−1)∗10,i∗10)的整数,i=1,2,3,4,总共有4个桶。
然后,对A[1..n]从头到尾扫描一遍,把每个A[i]放入对应的桶B[j]中。 再对这4个桶中每个桶里的数字排序,这时可用冒泡,选择,乃至快排,一般来说任何排序法都可以。
最后,依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,这样就得到所有数字排好序的一个序列了。
3. 算法实现
代码#include <stdio.h> #define N 13 #define NBUCKET 4 int array ={11, 23, 17, 35, 6, 19, 24, 1, 30, 29, 7, 11, 22}; int bucket[NBUCKET] ={0}; /* 以排序0~40间的数为列,分为4个桶[0,10),[10,20),[20,30),[30,40) */ int b_index[NBUCKET]={0}; /* 记录每隔桶中存放的数据个数 */ /* 打印数组 */ void print_array(int arr[],int len) { int i; for(i=0;i<N;i++) printf("%d ",arr[i]); printf("\n"); } /* 打印桶 */ void print_bucket() { int b,i; printf("Buckets num=%d\n",NBUCKET); for(b=0;b<NBUCKET;b++) /* 遍历各个桶 */ { printf("Bucket[%d]:\t",b); for(i=0;i<b_index;i++) { printf("%d ",bucket[b][i]); } printf("\n"); } } /* 插入排序 */ void insert_sort(int arr[],int len) { int tmp,i,j; for(i=1;i<len;i++) { if(arr[i]<arr[i-1]) { tmp=arr[i]; arr[i]=arr[i-1]; j=i-1; while(j>0 && tmp<arr[j-1]) { arr[j]=arr[ 4000 j-1]; j--; } arr[j]=tmp; } } } /* 冒泡排序 */ void bubble_sort(int arr[],int len) { int i, j, temp; for (j = 0; j < len - 1; j++) { for (i = 0; i < len - 1 - j; i++) { if(arr[i] > arr[i + 1]) /* 一次判断相邻元素大小,大于则交换 */ { temp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = temp; } } } } /* 桶排序 */ void bucket_sort(int arr[],int len) { int k,b,i; for(k=0;k<len;k++) /* 分配数据放各个入桶中 */ { b=arr[k]/10; /* 获取对应的桶 */ i=b_index[b]; /* 放入桶中的位置 */ bucket[b][i]=arr[k]; b_index[b]++; /* 桶中的数据加一 */ } print_bucket(); for(b=0;b<NBUCKET;b++) /* 各个桶内用插入排序 */ { //bubble_sort(bucket[b],b_index[b]); insert_sort(bucket[b],b_index[b]); } print_bucket(); k=0; for(b=0;b<NBUCKET;b++) /* 遍历各个桶,得到有序序列 */ { for(i=0;i<b_index[b];i++) { arr[k++]=bucket[b][i]; } } print_array(arr,len); } void main() { printf("Before...\n"); print_array(array,N); printf("Sorting...\n"); bucket_sort(array,N); printf("Sorted.\n"); }
[b]结果
Before... 11 23 17 35 6 19 24 1 30 29 7 11 22 Sorting... Buckets num=4 Bucket[0]: 6 1 7 Bucket[1]: 11 17 19 11 Bucket[2]: 23 24 29 22 Bucket[3]: 35 30 Buckets num=4 Bucket[0]: 1 6 7 Bucket[1]: 11 11 17 19 Bucket[2]: 22 23 24 29 Bucket[3]: 30 35 1 6 7 11 11 17 19 22 23 24 29 30 35 Sorted.
4. 算法分析
时间复杂度桶排序采用分配入桶和桶内排序结合的方法,假设有n个数字,有m个桶,如果数字是平均分布的,则每个桶里面平均有n/m个数字。如果对每个桶中的数字采用快速排序,那么整个算法的复杂度是
O(n+m∗n/m∗log(n/m))=O(n+nlogn−nlogm)
当m接近n的时候,桶排序复杂度接近O(n)。
以上复杂度的计算是基于输入的n个数字是平均分布这个假设的。这个假设是很强的 ,实际应用中效果并没有这么好。如果所有的数字都落在同一个桶中,那就退化成一般的排序了。
桶排序不是比较排序,不受到 O(nlogn) 下限的影响。
空间复杂度
由于桶排序需要一个长度为m的桶(m为序列中n个数的范围大小),所以其空间复杂度为O(m)。
稳定性
桶排序是稳定的。
总结
大部分时间复杂度都是 O(n2),也有部分排序算法时间复杂度是O(n\log n)。而桶式排序却能实现O(n)$ 的时间复杂度。桶排序的缺点是:
(1)首先是空间复杂度比较高,需要的额外开销大。排序有两个数组的空间开销,一个存放待排序数组,一个就是所谓的桶,比如待排序值是从0到m-1,那就需要m个桶,这个桶数组就要至少m个空间。
(2)其次待排序的元素都要在一定的范围内等等。
桶式排序是一种分配排序。分配排序的特定是不需要进行关键码的比较,但前提是要知道待排序列的一些具体情况。
相关文章推荐
- bucket sort 桶排序
- 桶排序(Bucket Sort)
- 桶排序(Bucket Sort)
- 桶排序和样本排序(Bucket Sort and Sample Sort)
- 桶排序(Bucket Sort),基数排序(Radix_Sort)
- 桶排序(Bucket Sort)----(排序算法七)
- 桶排序(BucketSort)
- 桶排序(bucket sort)
- 桶排序(Bucket Sort)----(排序算法七)
- 桶排序(bucket sort)
- (四)分配排序:桶排序(Bucket Sort)
- 桶排序(Bucket Sort)的数组实现
- 计数排序(Counting Sort)、桶排序(Bucket Sort)和基数排序(Radix Sort)
- 简化的桶排序(Bucket Sort)
- 桶排序(Bucket Sort)
- 基于非比較的排序:计数排序(countSort),桶排序(bucketSort),基数排序(radixSort)
- 桶排序(Bucket Sort)
- 算法总结系列之六: 桶排序(Bucket Sort)
- 基于非比较的排序:计数排序(countSort),桶排序(bucketSort),基数排序(radixSort)
- Bucket sort 桶排序(含EOF)