【为什么要学排序?】
在我们的生活中,方方面面都用到排序。你可以仔细想想身边的排序,站队的时候按身高排序,考试按成绩排序,商品按名称与用途排序,博客按发布时间排序······总之,生活中离不开这些排序,排序使我们的世界变得更加有规律,是人们的生活更加方便。
+++++++++++++++++++++++++++++++++++假装分割线
这次我们先一起学习一个简单快捷的排序算法----桶排序。其实啊,这次的桶排序并不是一个真正的桶排序,只是它的一个简易版,真正的桶排序在以后会和大家见面。
废话就先说到这,下面介绍简易的桶排序:
假设给你一串数字: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个桶。所以我们还需要学习更多的排序算法。
下节:冒泡排序。