您的位置:首页 > 编程语言 > C语言/C++

【继续思考】排序算法——基数排序与桶排序

2015-07-01 22:48 375 查看
基数排序可以用于较大数的排序,克服了计数排序的这一缺点。

基数排序思想并不复杂,通常我们排序有两种思路,从高位到低位,或者,从低位到高位。比如比较年月日,我们通常会先比较年份,年份相等时,再比较月份,月份相等时,再比较日期。

下面这段话,我觉得写得很简单通俗,帮助了我理解(来源http://blog.csdn.net/hazir/article/details/6396194)

“计数排序的缺点很明显,需要额外的空间C来作为计数数组,虽然时间复杂度为O(n+k),但当输入序列里元素取值很大的时侯,如k=O(n2),时,此时时间复杂度已经达到n2数量级了,空间的消耗也是让人无法承受的。这里介绍一种另一种线性排序算法——基数排序,可以应对数值很大的情况。

基数排序,即一个数位一个数位地进行排序,平常生活中我们经常使用的一种算法思想:如要对一个日期进行排序,日期中由年、月、日组成的,对于这个问题,我们经常使用的是先比较年份,如果相同再比较月份,如果还相同就比较日。

同理,我们比较一组数,也可以采取这种思想。例如我们使用这种思想对下面四个数进行排序:123、312、245、531,第一次按百位排序:123、245、312、531;第二次按十位排序:312、123、531、245;第三次按个位数排序:531、312、123、245。咦?为什么最后排出来的结果并不是预期的那样?原因是我们从高位开始排序,已经差不多整体有序之后,再到低位时,又全部被打乱了。如果我们之后这样做就不会乱了:高位相同的数,再将它们的低位进行排序….不过这个实现一起比较困难一些。

这里,我们换成从最低有效位到最高有效位进行排序,那么还是上面那个例子:

   个位 =>  十位 =>  百位

   531      312      123

   312      123      245

   123      531      312

   245      245      531

可以看到结果正确。通俗地讲,之所以先排低位再排高位,是因为越是后排的数位,其对结果次序的影响越大,很显然是高位比低位对数的大小影响大!


所以,其实思想不复杂,下面是还没实现的代码,今天晚上有点晚了,脑子不是很清醒,先放在这里,明天再继续写:(看算法思想,请忽略下面的代码)

//基数排序
int main()
{
int a[20] = {329,457,1234,23,56,6,9,13546,7,164,123,124,224,223,456,457,156,124567,987,20};
int b[20] = {0};
int temp[10] = {0};//,每一位的数不会超过9

int max = 0;

for (int i = 0; i < 20; i++)//找出位数最多的数
{
int num = a[i];
int res = 1;
while (num / 10)
{
num = num / 10;
res++;
}
if (res>max)
max = res;
}

for (int i = 0; i < max; i++)//控制从低位到高位开始比较
{
for (int j = 0; j < 20; j++)
{
int num = a[j];
int wei = num % 10;

}
}

return 0;
}

觉得自己好像已经理解基数排序了,今天发现自己似乎并没有理解得很透。看了一篇文章,觉得写得很好
http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html
其实基数排序,可以从最低位开始排,也可以从最高位开始排。最高位开始排的这种思想,其实感觉有点类似与桶排序

二、桶排序思想

桶排序思想也不是很复杂(其实我一直觉得理解堆排序是最复杂的)

桶排序要求数组里的元素服从均匀分布(因此使用的范围不是非常广)。先按照某种规则,将待排序数组元素放入桶中。如,0-1000的数,用100个桶来装,每个桶可以装10个。这样0-10,10-20,20-30分出来,可以将待排序数装入其中,再对每个桶的元素进行排序。暂时不写代码了,因此目前对链表和指针的操作还不是很熟练,过段时间过来写代码的实现部分。(算法导论第三版,桶排序很好理解)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息