桶排序
思想:要排序的数据的范围为小于M的正整数。这样,使用一个大小为M的bucket数组,数组初始化为0。
bucket数组的每个单元称为“桶”。然后依次扫描待排序数据(A1,A2,A3,A4,……,Ai),读到Ai的时候,bucket[Ai]增加1。
这样,待排序数据读完后,扫描数组bucket,打印出排序表即可。
void bucketsort (int *arr, int n)
{
//寻找最大数
int max = 0;
for(int i = 0; i < n; i++)
if (arr[i] > max)
max = arr[i];
//创建m个桶
int m = max + 1;
int bucket[m];
for(int i=0; i < m; i++)
bucket[i]=0;
for(int i=0; i < n; i++)
++bucket[arr[i]];
for(int i=0, j=0; j < m; ++j)
for (int k=bucket[j]; k > 0; --k)
arr[i++]=j;
}
总结:桶排序,当待排序数稀疏的时候,将会有大量的空桶,造成空间浪费。同样,如果待排序数空间范围很大,将会产生很多桶,
这样势必会占用大量空间。
基数排序
思想:多趟桶排序,节省空间。首先通过最低有效位进行排序,然后是次低有效位……。
void radixsort(int *arr, int n)
{
int tmp[n];
int bucket[10];
int m = 0, exp = 1;
for (int i = 0; i < n; i++)
if (arr[i] > m)
m = arr[i];
while (m / exp > 0)
{
for(int i = 0; i < 10; i++)
bucket[i] = 0;
//统计各个桶中应放置元素个数
for(int i = 0; i < n; i++)
bucket[arr[i] / exp % 10]++;
//各桶前总共含有多少个元素
//方便后面放置元素
for (int i = 1; i < 10; i++)
bucket[i] += bucket[i - 1];
//直接放置在数组中
//放置位置通过bucket中值指定
for (int i = n - 1; i >= 0; i--)
tmp[--bucket[arr[i] / exp % 10]] = arr[i];
for (int i = 0; i < n; i++)
arr[i] = tmp[i];
exp *= 10;
}
}
总结:代码总体思想是先放置,然后收集起来。再放置,在收集,通过这样的方式,最终得到有序结果。
基数排序相对于桶排序,是以时间换空间。