1.桶排序的基本思想
桶排序的基本思想是将一个数据表分割成许多buckets,然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法。也是典型的divide-and-conquer分而治之的策略。它是一个分布式的排序,介于MSD基数排序和LSD基数排序之间。
桶排序算法要求,数据的长度必须完全一样,程序过程要产生长度相同的数据
关于基数排序,可以参考《常用12大排序算法之九:基数排序(LSD+MSD)-桶子法排序》。
2.桶排序的基本流程
(1)具体过程
建立一堆buckets;
遍历原始数组,并将数据放入到各自的buckets当中;
对非空的buckets进行排序;
按照顺序遍历这些buckets并放回到原始数组中即可构成排序后的数组。
(2)代码实现过程
设置一个定量的数组当作空桶子;
寻访序列,并且把项目一个一个放到对应的桶子去;
对每个不是空的桶子进行排序;
从不是空的桶子里把项目再放回原来的序列中。
3.桶排序的复杂度
桶排序利用函数的映射关系,减少了几乎所有的比较工作。实际上,桶排序的f(k)值的计算,其作用就相当于快排中划分,已经把大量数据分割成了基本有序的数据块(桶)。然后只需要对桶中的少量数据做先进的比较排序即可。
对N个关键字进行桶排序的时间复杂度分为两个部分:
(1) 循环计算每个关键字的桶映射函数,这个时间复杂度是O(N)。
(2) 利用先进的比较排序算法对每个桶内的所有数据进行排序,其时间复杂度为 ∑ O(Ni*logNi) ,其中Ni 为第i个桶的数据量。
很显然,第(2)部分是桶排序性能好坏的决定因素。尽量减少桶内数据的数量是提高效率的唯一办法(因为基于比较排序的最好平均时间复杂度只能达到O(N*logN)了)。因此,我们需要尽量做到下面两点:
(1) 映射函数f(k)能够将N个数据平均的分配到M个桶中,这样每个桶就有[N/M]个数据量。
(2) 尽量的增大桶的数量。极限情况下每个桶只能得到一个数据,这样就完全避开了桶内数据的“比较”排序操作。 当然,做到这一点很不容易,数据量巨大的情况下,f(k)函数会使得桶集合的数量巨大,空间浪费严重。这就是一个时间代价和空间代价的权衡问题了。
对于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)。
总结:桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好的时间复杂度达到O(N)。当然桶排序的空间复杂度为O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的。此外,桶排序是稳定的。
4.桶排序算法C语言源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /** * 算法君:一个专业的算法学习分享网站 * 算法君:专业分享--数据剖析--算法精解 * 算法君:http://www.suanfajun.com */ #include<stdio.h> #define Max_len 10 //数组元素个数 // 打印结果 void Show(int arr[], int n) { int i; for ( i=0; i<n; i++ ) printf("%d ", arr[i]); printf("\n"); } //获得未排序数组中最大的一个元素值 int GetMaxVal(int* arr, int len) { int maxVal = arr[0]; //假设最大为arr[0] for(int i = 1; i < len; i++) //遍历比较,找到大的就赋值给maxVal { if(arr[i] > maxVal) maxVal = arr[i]; } return maxVal; //返回最大值 } //桶排序 参数:数组及其长度 void BucketSort(int* arr , int len) { int tmpArrLen = GetMaxVal(arr , len) + 1; int tmpArr[tmpArrLen]; //获得空桶大小 int i, j; for( i = 0; i < tmpArrLen; i++) //空桶初始化 tmpArr[i] = 0; for(i = 0; i < len; i++) //寻访序列,并且把项目一个一个放到对应的桶子去。 tmpArr[ arr[i] ]++; for(i = 0, j = 0; i < tmpArrLen; i ++) { while( tmpArr[ i ] != 0) //对每个不是空的桶子进行排序。 { arr[j ] = i; //从不是空的桶子里把项目再放回原来的序列中。 j++; tmpArr[i]--; } } } int main() { //测试数据 int arr_test[Max_len] = { 8, 4, 2, 3, 5, 1, 6, 9, 0, 7 }; //排序前数组序列 Show( arr_test, Max_len ); //排序 BucketSort( arr_test, Max_len); //排序后数组序列 Show( arr_test, Max_len ); return 0; } |
5.桶排序算法C++源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | /** * 算法君:一个专业的算法学习分享网站 * 算法君:专业分享--数据剖析--算法精解 * 算法君:http://www.suanfajun.com */ #include<iostream> #include<vector> using namespace std; class A{ public: int length; vector<int> a; }; void insertSort(vector<int> &b){ int size = b.size(); int key,i; for(int j=1;j<size;j++){ key=b[j]; i=j-1; while(i>=0&&b[i]>key){ b[i+1]=b[i]; i=i-1; } b[i+1]=key; } } void bucketSort(A &array){ int n = array.length; vector<vector<int>> b; for(int i=0;i<array.length;i++){ vector<int> tmp; b.push_back(tmp); } for(int i=0;i<array.length;i++){ int tmp = array.a[i]; if(array.a[i]/10==0) b[0].push_back(tmp); if(array.a[i]/10==1) b[1].push_back(tmp); if(array.a[i]/10==2) b[2].push_back(tmp); if(array.a[i]/10==3) b[3].push_back(tmp); if(array.a[i]/10==4) b[4].push_back(tmp); if(array.a[i]/10==5) b[5].push_back(tmp); if(array.a[i]/10==6) b[6].push_back(tmp); if(array.a[i]/10==7) b[7].push_back(tmp); if(array.a[i]/10==8) b[8].push_back(tmp); if(array.a[i]/10==9) b[9].push_back(tmp); } for(int i=0;i<10;i++){ insertSort(b[i]); } for(vector<vector<int>>::iterator iter=b.begin();iter!=b.end();iter++){ for(vector<int>::iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++){ cout<<*iter2<<endl; } } } int main(){ A array; int m; array.length=10; array.a.push_back(23); array.a.push_back(11); array.a.push_back(16); array.a.push_back(82); array.a.push_back(98); array.a.push_back(73); array.a.push_back(63); array.a.push_back(19); array.a.push_back(31); array.a.push_back(26); bucketSort(array); cin>>m; return 0; } |