👏这个笔记是看了《啊哈!算法》之后,自己的一些小总结。

1.一个简陋的桶排序:

在说桶排序算法时,我们来通过一个例子来大概了解一下桶排序是什么:

  • 对8,5,5,3,2这五个数进行从大到小的排序:
  • 想法如下:
    1.构建一个数组a[10],并将其置零
    2.对每个出现的数,在数组对应的位置上加一。(出现一次就加一,例子中5出现了两次,那么a[5] = 2)
    3.然后将数组倒序输出,如果a[i] = 0,则不输出,若不为0则输出i,且输出一次将数组减一。
  • 代码如下:
    #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); //把每一个数读到变量t中
        a[t]++; //进行计数
    }
    for(i=0;i<=10;i++) //依次判断a[0]~a[10]
        for(j=1;j<=a[i];j++) //出现了几次就打印几次
            printf("%d ",i);
    return 0;
    }
    
  • 但这个方法明显有很大的缺陷:
  • 1.例如当要求排序的数只有3,5,999时,我们却需要创建一个a[1000]的数组,造成了极大的浪费;
  • 2.但要求比较的数不止是整数时,也不能使用这个算法;
  • 所以这里叫做简陋的桶排序,真正的桶排序会解决上述问题,这里先不介绍。

2.冒泡排序:

依旧从一个例子出发:

  • 对12,35,99,18,76这五个数进行排序:

  • 冒泡的基本思想是:每比较相邻的两个元素,如果他们顺序错误就把他们交换过来。

  • 在例子中,将第一位与第二位比较,12小,交换位置,35到第一位,12到第二位,将第二位继续与第三位相比,再次交换顺序,一直进行下去,直到12在第五位(即最后一位),这个数组会变成:35,99,18,76,12(此时最小的数已到达第五位了)

  • 再进行第二次冒泡,将第一位与第二位比较,35小,交换顺序,第二位与第三位比较,18小,不交换顺序,第三位与第四位比较,18小,交换顺序,此时数组为:99,35,76,18,12(此时第二小的数已经到达第四位)

  • 再对后面的数进行操作,数组最终会变成:99,76,35,18,12

  • 我们来总结一下:

  • 1.每进行一次冒泡,就有一个数归位,例如第一次冒泡只能将第五位归位,第二次将第四位归位,后面以此类推。

  • 2.对于n个数的排序,我们只需要将n-1个数进行归位。

  • 依照这个思想,对于任意n个数的排序,代码如下:

#include<stdio.h>
int main()
{
	int a[100],i,j,t,n;
	scanf("%d",&n);     //输入一个数n,表示接下来有n个数
	for(i=1;i<=n;i++)   //循环读入n个数到数组a中
	{
		scanf("%d",&a[i]);
	}
    //冒泡排序的核心部分
	for(i=1;i<=n-1;i++)     //n个数排序,只用进行n-1趟
	{
		for(j=1;j<=n-i;j++)
		{
			if(a[j]<a[j+1])
			{
				t = a[j+1]; a[j+1] = a[j]; a[j] = t;    //比较大小并交换
				}	
		}
	}
	for(i=1;i<=n;i++)
		printf("%d ",a[i]);
	return 0;
}