1.问题提出与描述
有时我们想让某数组升序排列。不妨设num[1],num[2]…num[n]来表示该数组。可以从第一个元素开始,比较相邻元素。若a[1]大于a[2]时,交换位置。现在比较a[2]和a[3],若a[2]>a[3],互换位置。按照这种逻辑,可以逐个比较相邻的元素,直到列表尾部。第一次处理中,需要n-1次比较。需要进行n-1次比较,计数下标i的值从1递增到n-1。每处理一趟,待处理数据元素的集合中的最大值被交换到最右侧。然后集合元素除去当前最大值,接着对剩余元素集合做相同处理。一个大小为n的数组,需要n-1趟处理。
可以观察到,在每趟处理中,当前最大元素被不断向尾部移动,每趟处理完毕,最“轻”的元素就排到队列的第一个位置。这有点像气泡从瓶底向瓶口浮动。因此这种拍戏算法被称为冒泡排序。(bubble sort)
2.算法描述
(1).将n个元素保存到数组a[n]中
(2).重复第3步,每一趟的值从1递增到n-1,每趟处理中,i的值从1递增到n-1.
(3).如果a[i]和a[i+1],那么
temp=a[i]
a[i]=a[i+1]
a[i+1]=temp;
(4).数组a[]排序完毕。可显示数组元素
3.代码设计
#include<stdio.h>
int main(){
int i,pass,n; // i计数下标 pass趟数 n数据个数
int a[70],temp; //先开辟长度为70的数组长度,temp为一个临时值 ,交换的中间变量
printf("how many elements?");
scanf("%d",&n);
printf("enter the elements: ");
for(i=1;i<=n;i++) //利用for循环依次输入数据的元素
scanf("%d",&a[i]);
for(pass=1;pass<=n-1;pass++) //外层for循环限制排序数组的最多趟数为n趟
{
for(i=1;i<=n-pass;i++) //i元素下标,从i到第n-1个(开始写成n,未考虑到第i+1个数)
{
if(a[i]>a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
printf("the sorted elements :");
for(i=1;i<=n;i++)
printf("%3d",a[i]);
}
4.实现
5.实例分析
初始元素 3 1 6 2 7
第一趟 1 3 2 6 7
第二趟 1 2 3 6 7
第三趟 1 2 3 6 7
第四趟 1 2 3 6 7
6.算法小改进
由算法的思想可知,在每一趟的遍历中,总是把最大的数排列到数组的最右边,所以在每一趟的遍历中,都需要由第一个数遍历到最后一个数,i从1一直指向n-1,即遍历n-1次。这样或导致时间的浪费。所以可以改进为在第一趟遍历时,遍历整个数组,在第二趟遍历时,只需遍历由1到第n-1个数,因为最右边的数已处于最大位置,无需再进行比较。以此类推,即第三趟遍历的时候,需要比较n-3次。由上述规律可以得出,在每趟遍历的时候,只需要遍历n-psss(趟数),即可使代码运行更加高效。所以,内层for循环中,i的值每次随着pass的值增大而变化。内层for循环可以优化为
for(i=1;i<=n-pass;i++)
在上述例子中,,第一趟不变。第二趟只需比较 1 3 2 6 四个数据,第三趟比较 1 2 3三个数据。