桶排序是按值域划分桶,
基数排序是按位数划分桶。
分类(LSD和MSD):
① 最低位优先LSD法:先从最低位开始排序,再对次低位排序,直到对最高位排序后得到一个有序序列。
② 最高位优先MSD法:先从最高位开始排序,再对次高位排序,直到对最低位排序后得到一个有序序列。
【基本思想】
分配+收集
① 基数排序也叫桶排序或箱排序:设置若干个箱子,将关键字为的记录放入第k个箱子,然后在按序号将非空的连接。
② 要求箱子个数是有范围的,例如:数字是有范围的,均由0-9这十个数字组成,则只需设置十个箱子,相继按个、十、百…进行排序。
例:
(614,738,921,485,637,101,215,530,790,306)
void radixsort(int num[],int len)
{
int i,j,k,l,digit;
int allot[10][N];
memset(allot,0,sizeof(allot));
for(i=1;i<=D;i++)
{
int flag=0;
for(j=0;j<len;j++)
{
digit=getdigit(num[j],i);
k=0;
while(allot[digit][k])
k++;
allot[digit][k]=num[j];
if(digit)
flag=1;
}
if(!flag)
break;
l=0;
for(j=0;j<10;j++)
{
k=0;
while(allot[j][k]>0)
{
num[l++]=allot[j][k];
k++;
}
}
memset(allot,0,sizeof(allot));
}
}
时间复杂度:O(k*(n+m))
关键字:分配的标准,如按百位排序,按千位排序……
k:关键字个数,表示分配多少趟。
m:关键字取值范围为m个值,也就是桶的个数。
n:元素个数。
空间复杂度:S(n)=O(n+m)
稳定性:稳定
优点:算法效率高;
缺点:关键字的取值范围有限。
“桶排序”又称“箱排序”。
【基本思想】
桶排序是将待排序序列中处于相同值域的元素存入同一个桶中,即将一个数据表分割成许多桶,然后每个桶中的元素各自排序。它采用分治策略,是一种分布式的排序方法。
【基本步骤】
① 根据待排序序列中最大元素和最小元素的差值和映射规则,确定申请的桶个数;
② 遍历待排序序列,将每一个元素存储到对应的桶中;
③ 分别对每一个桶中元素进行排序,并存储到原序列中,获得一个已排序序列。
bool buckertSort(int array[], size_t arrLen, size_t bucketSize) {
const int DEFAULT_BUCKET_SIZE = 10;
if(arrLen < 2) {
return true;
}
if (bucketSize < 1) {
bucketSize = DEFAULT_BUCKET_SIZE;
}
// Find the scope of the array
int min = array[0];
int max = array[0];
for (size_t i = 1; i < arrLen; ++i)
{
if (min > array[i]) {
min = array[i];
}
else if (max < array[i]) {
max = array[i];
}
}
// Create buckets
int **buckets = new int*[bucketSize]();//创建桶
int *bucketLen = new int[bucketSize]();//创建记录当前桶内数据个数,初始化为0
//计算桶的数据的范围,可以把它想象为把一个线段,平均分成bucketSize个小线段,小线段的长度就是bucketScope
//为什么+1,大家知道min=10,max=90,其实有81个数据,如果按照(90-10)/10来分,你桶里面的数据范围只能从10到89,所以要用1补齐
int bucketScope = floor((max - min)/bucketSize) + 1;
//创建桶空间,只有桶里面有空间才能放数据
for (size_t j = 0; j < bucketSize; j++)
{
buckets[j] = new int[arrLen]();
}
int bucketIndex = -1;
// Put array value to buckets
for (size_t k = 0; k < arrLen; ++k)
{
bucketIndex = floor((array[k] - min)/bucketScope); //计算数据所在桶的下标
buckets[bucketIndex][bucketLen[bucketIndex]++] = array[k];//将数据放入桶中
}
// Sort value in bucket and put ordered value back to array
int arrayIndex = 0;
for (size_t l = 0; l < bucketSize; l++)
{
if (bucketLen[l] > 0) {
insertSort(buckets[l], bucketLen[l]); //对桶内数据进行排序
for (size_t m = 0; m < bucketLen[l]; ++m) {
array[arrayIndex++] = buckets[l][m];//将排好序的数据放回原数组
}
}
delete [] buckets[l];
buckets[l] = NULL;
}
delete [] buckets;
delete [] bucketLen;
return true;
}
【基本思想】
若待排序序列的元素均为非负整数,且最大值为max,则分配max+1个桶,每个桶的编号(下标)就等于待排序元素的值,每个桶的元素值就是存入桶中的待排序元素个数。为了描述方便,我们将桶序列称为统计数组。
【基本步骤】
(1)根据待排序序列中最大元素值,确定申请的桶个数,并将桶全部清空;
(2)统计待排序序列中每个值为i的元素出现的次数,存入编号为i的桶;
(3)依次把数据从桶里倒出来,存储到原序列中,获得一个已排序序列。
#include
using namespace std;
int main()
{
int arr[]={3,5,6,9,5,2,4,7};
int len=8;
int count[8]={0};//9-2+1
for(int i=0;i<len;i++)
{
count[arr[i]]++;
}
for(int i=0;i<8;i++)
{
while(count[i]!=0)
{
cout<<i<<" ";
count[i]--;
}
}
return 0;
}