(快速总结了桶排序和基数排序,由于近期项目比较忙,很多地方没有考虑完整,日后有空再回来修改)
桶排序:
将数组分配到有限数量的桶子里,每个桶子再个别排序。
下列中:将数据作为桶(数组)的下标存储,适合于数据值的范围比较小;比如:求在1G大小的字符串中,出现次数最多的那个字符;因为字符char的边界是[0...255],就可以将所有的字符遍历、存储到[0...255]桶中(数组下标).
基数排序:
可以理解为对桶排序的扩充,将数据分别按个位、十位、百位...分别放入buckets[0...9][num]的桶中。
即:先将个位数存储到[0...9]的桶中,个位数将排好序
再按照个位数排好的序,将十位数存储到[0...9]的桶中,十位数排好序(个位数上一轮已经排好序)...
再百位,千位...每次放入桶中后,桶的顺序、桶内数据的顺序是排好的。
例如:
下例中数组:
int array[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
按个位依次排序(到桶中)
0|
1|1,
2|2,342
3|343,123,43,4343,433,3
4|654
5|
6|
7|687
8|
9|
按值的顺序存入到array[] = {1,2,342,343,123,43,4343,433,3,654,687};
由此可见,个位数是排好序的;
再将array[] = {1,2,342,343,123,43,4343,433,3,654,687}按十位数依次排序
0|1,2,3
1|
2|123
3|433
4|342,343,43,4343
5|654
6|
7|
8|687
9|
按值的顺序存入到array[] = {1,2,3,123,433,342,343,43,4343,654,687}
由此可见,个位数、十位数是排好序的;
再将array[] = {1,2,3,123,433,342,343,43,4343,654,687}按百位数依次排序
0|1,2,3,43
1|123
2|
3|342,343,4343
4|433
5|
6|654,687
7|
8|
9|
按值的顺序存入到array[] = {1,2,3,43,123,342,343,4343,433,654,687}
由此可见,个位数、十位数、百位数是排好序的;
再将array[] = {1,2,3,43,123,342,343,4343,433,654,687}按千位数依次排序
0|1,2,3,43,123,342,343,433,654,687
1|
2|
3|
4|4343
5|
6|
7|
8|
9|
按值的顺序存入到array[] = {1,2,3,43,123,342,343,433,654,687,4343}
桶排序:
将数组分配到有限数量的桶子里,每个桶子再个别排序。
下列中:将数据作为桶(数组)的下标存储,适合于数据值的范围比较小;比如:求在1G大小的字符串中,出现次数最多的那个字符;因为字符char的边界是[0...255],就可以将所有的字符遍历、存储到[0...255]桶中(数组下标).
基数排序:
可以理解为对桶排序的扩充,将数据分别按个位、十位、百位...分别放入buckets[0...9][num]的桶中。
即:先将个位数存储到[0...9]的桶中,个位数将排好序
再按照个位数排好的序,将十位数存储到[0...9]的桶中,十位数排好序(个位数上一轮已经排好序)...
再百位,千位...每次放入桶中后,桶的顺序、桶内数据的顺序是排好的。
例如:
下例中数组:
int array[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
按个位依次排序(到桶中)
0|
1|1,
2|2,342
3|343,123,43,4343,433,3
4|654
5|
6|
7|687
8|
9|
按值的顺序存入到array[] = {1,2,342,343,123,43,4343,433,3,654,687};
由此可见,个位数是排好序的;
再将array[] = {1,2,342,343,123,43,4343,433,3,654,687}按十位数依次排序
0|1,2,3
1|
2|123
3|433
4|342,343,43,4343
5|654
6|
7|
8|687
9|
按值的顺序存入到array[] = {1,2,3,123,433,342,343,43,4343,654,687}
由此可见,个位数、十位数是排好序的;
再将array[] = {1,2,3,123,433,342,343,43,4343,654,687}按百位数依次排序
0|1,2,3,43
1|123
2|
3|342,343,4343
4|433
5|
6|654,687
7|
8|
9|
按值的顺序存入到array[] = {1,2,3,43,123,342,343,4343,433,654,687}
由此可见,个位数、十位数、百位数是排好序的;
再将array[] = {1,2,3,43,123,342,343,4343,433,654,687}按千位数依次排序
0|1,2,3,43,123,342,343,433,654,687
1|
2|
3|
4|4343
5|
6|
7|
8|
9|
按值的顺序存入到array[] = {1,2,3,43,123,342,343,433,654,687,4343}
这时整个数组已经按升序排序完成。
#include<math.h>
#include <iostream>
using namespace std;
//桶排序
int bucketSort()
{
int array[]={9,8,7,9,8,7,1,2,3,0};
int n = sizeof(array)/sizeof(array[0]);
int bucket[sizeof(array)/sizeof(array[0])] = {0};
for(int i = 0; i<n; i++)
{
int n = array[i];
//用array数据作为bucket数组下标,因此下标的范围决定了数组的大小
//++用于重复的数据
bucket[n]++;
}
for(int j = 0; j<n; j++)
{
//如果桶内没有数据,则跳过;有数据,输出下标。
while(bucket[j]--)
cout<<j<<endl;
}
}
//获取数字的位数
int getLoopTimes(int num)
{
int count = 1;
while(num = num/10)
{
count++;
}
return count;
}
//查询数组中的最大数
int findMaxNum(int *p, int n)
{
int max = 0;
for(int i = 0; i < n; i++)
{
if(*(p + i) > max)
{
max = *(p + i);
}
}
return max;
}
//将数字分配到各自的桶中[0...9],然后按照桶的顺序输出排序结果
void bucketsInRadix(int *p, int n, int loop)
{
cout<<"===========Loop = "<<loop<<"==========="<<endl;
//建立一组桶,10为桶的序列[0...9]
//11为桶的容量,即数组的容量n,也是单桶的最大容量
int buckets[10][11] = {0};
//tempNum用于求余数的值;按照个位、十位、百位分别除1,10,100用于求位数值
int tempNum = (int)pow(10, loop - 1);
int i, j;
//int x = 0;
cout<<"buckets: ";
//i为数组数据遍历的变量
for(i = 0; i < n; i++)
{
//确定基数(尾数)
int row_index = (*(p + i) / tempNum) % 10;
//用于同“基数”存储,即同一个桶中数据的存储
//如果桶中某一位不为0,说明该位置被占用,存储到下一个位置。
//也可以简化为:buckets[row_index][x++] = *(p + i);但是桶内数据没有连续存储
for(j = 0; j < n; j++)
{
if(buckets[row_index][j] == 0)
{
buckets[row_index][j] = *(p + i);
break;
}
}
cout<<buckets[row_index][j]<<" ";
}
cout<<endl;
//将桶中的数,倒回到原有数组中
cout<<"......p: ";
int k = 0;
//基数升序
for(i = 0; i < 10; i++)
{
//同“基数”值的倒回,即按照桶序列[0...9]中依次倒回
for(j = 0; j < n; j++)
{
//i对应桶,j对应桶内的值,j最大为数组的值
if(buckets[i][j] != 0)
{
*(p + k) = buckets[i][j];
buckets[i][j] = 0;
cout<<*(p + k)<<" ";
k++;
}
}
}
cout<<endl;
}
//基数排序
void radixSort(int *p, int num)
{
//获取数组中的最大数
int maxNum = findMaxNum(p, num);
//根据最大数获取最大的位数
//loopTimes即需要按位存储、排序的次数
int loopTimes = getLoopTimes(maxNum);
//对每一位进行桶分配
//第一次循环之后,个位数已经排好序
//第二次循环之后,十位数排好序(个位数上一轮已经排好序)...
for(int i = 1; i <= loopTimes; i++)
{
bucketsInRadix(p, num, i);
}
}
int main()
{
cout<<"==============Test Bucket Sort ==============\n"<<endl;
bucketSort();
cout<<"==============Test Radix Sort ==============\n"<<endl;
int array[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
//计算数组长度
int size = sizeof(array) / sizeof(int);
//基数排序
radixSort(array, size);
//打印排序后的结果
for(int i = 0; i < size; i++)
{
cout<<array[i]<<endl;
}
}