排序算法之最简单的排序----桶排序

为什么要学排序?
在我们的生活中,方方面面都用到排序。你可以仔细想想身边的排序,站队的时候按身高排序,考试按成绩排序,商品按名称与用途排序,博客按发布时间排序······总之,生活中离不开这些排序,排序使我们的世界变得更加有规律,是人们的生活更加方便。
+++++++++++++++++++++++++++++++++++假装分割线
这次我们先一起学习一个简单快捷的排序算法----桶排序。其实啊,这次的桶排序并不是一个真正的桶排序,只是它的一个简易版,真正的桶排序在以后会和大家见面。
废话就先说到这,下面介绍简易的桶排序:
假设给你一串数字:2 3 5 7 7,想要把它们按照从小到大排序怎么排?
这里只需借助一个一维数组就可以了。首先,我们申请一个大小为11的数组int a[11]。现在我们就有了11个变量,编号从a[0]~a[10]。我们要先将这些变量都初始化为0,表示这些数字出现的次数还是0。
下面开始处理这些数字,比如,第一个数字为2,我们就将对应的a[2]加1,表示2这个数字出现过一次。
以此类推,得到a[2]=1,a[3]=1,a[5]=1,a[7]=2,其余的都为0。
接下来,我们只需将出现过的数字打印出来就可以了,出现几次就打印几次。
a[0]=0,表示“0”未出现过,不打印。
a[1]=0,表示“1”未出现过,不打印。
a[2]=1,表示“2”出现过1次,打印2。
a[3]=1,表示“3”出现过1次,打印3。
a[4]=0,表示“4”未出现过,不打印。
a[5]=1,表示“5”出现过1次,打印5。
a[6]=0,表示“6”未出现过,不打印。
a[7]=2,表示“7”出现过2次,打印7 7。
a[8]=0,表示“8”未出现过,不打印。
a[9]=0,表示“9”未出现过,不打印。
a[10]=0,表示“10”未出现过,不打印。
最终输出如下“2 3 5 7 7”。
c语言代码实现如下:

#include<stdio.h>
int main(){
    int a[11],i,j,t;
    for(i=0;i<=10;i++)
        a[i]=0;     //初始化为0 
    for(i=1;i<=5;i++)   //循环读入5个数
    {
        scanf("%d",&t)
        a[t]++;
    }
    for(i=0;i<=10;i++)
        for(j=1;j<=a[i];j++)
            printf("%d ",i);
    getchar();getchar();
    return 0;
}

如果想要实现从大到小排序,只需要将for(i=0;i<=10;i++)改成for(i=10;i>=0;i–)就可以了。真正的桶排序比这个要复杂,所以就把它就做简易的桶排序。
这个算法就好比有11个桶,标号从0 ~10。每出现一个数,就向对应的小桶里加一个小旗子,最后只要数数每个桶里有几个小旗子就可以了。
图片来自《啊哈!算法》
现在,我们尝试输入n个0~1000之间的整数,将它们从大到小排序。这时,我们需要1001个桶。
c语言代码实现如下:

#include<stdio.h>
int main(){
    int a[1001],i,j,t,n;
    for(i=0;i<=1000;i++)
        a[i]=0;
    scanf("%d",&n);//输入一个数,表示接下来有n个数参与排序
    for(i=1;i<=n;i++)   
    {
        scanf("%d",&t)
        a[t]++;
    }
    for(i=1000;i>=0;i--)
       for(j=1;j<=a[i];j++)
           printf("%d ",i);
    getchar();getchar();
    return 0;
}

Java语言实现如下:

import java.util.Scanner;

public class Tong {
	public static void main(String[] args) {
		int i,j,t,n;
		int a[]=new int [1001];
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		for(i=0;i<1000;i++)
			a[i]=0;
		for(i=0;i<n;i++) {
			t=sc.nextInt();
			a[t]++;
		}
		for(i=1000;i>=0;i--)
			for(j=1;j<=a[i];j++)
				System.out.print(i+" ");
	}
}

时间复杂度:
设,共有M个桶,N个数,全部代码一共循环了M+N+M+N次。时间复杂度即为O(2*(M+N)),忽略较小常数即为O(M+N)。由时间复杂度可以看出,这是一个非常快的排序算法。
桶排序虽然快,但是它还是有缺点的,比如,如果我们把这些数字对应一个名字,xiaoming 2,xiaohong 3,xiaogang 5,xiaozhang 7,xiaowang 7,想要输出他们的名字可就没那么简单了,桶排序还有一个非常致命的缺点,它很浪费空间!如果要排序5个0~90000000之间的数,就要创建90000001个桶。所以我们还需要学习更多的排序算法。

下节:冒泡排序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值