1.问题描述
对NNN个整数(数据由键盘输入)进行升序排列。
2.问题分析
对于NNN个数因其类型相同,我们可利用数组进行存储。
冒泡排序是在两个相邻元素之间进行比较交换的过程将一个无序表变成有序表。
冒泡排序的思想:首先,从表头开始往后扫描数组,在扫描过程中逐对比较相邻两个元素的大小。
若相邻两个元素中,前面的元素大于后面的元素,则将它们互换,称之为消去了一个逆序。
在扫描过程中,不断地将两相邻元素中的大者往后移动,最后就将数组中的最大者换到了表的最后,这正是数组中最大元素应有的位置。
然后,在剩下的数组元素中(n-1个元素),重复上面的过程,将次小元素放到倒数第2个位置。
不断重复上述过程,直到剩下的数组元素为0为止,此时的数组就变为了有序。
假设数组元素的个数为nnn,在最坏情况下需要的比较总次数为:((n1)+(n2)+...+2+1)=n(n1)/2((n-1)+(n-2)+...+2+1)=n(n-1)/2((n1)+(n2)+...+2+1)=n(n1)/2。
3.算法设计
冒泡排序的过程我们用示意图简单的表示,从整个排序过程中寻找规律,nnn个元素只需比较n1n-1n1次即可。
假设一个数组中有7个元素,现在对这7个元素进行排序,只需比较6轮即可得到所要的有序序列。
示意图中最后加粗的数字即为经过一轮交换位置固定的数字。示意图如下:
动图演示
清楚了冒泡排序的过程,我们再来看一个动态图
4.程序设计
设计一
数组名用a表示、数组下标用j表示,数组中相邻两个元素的下标可表示为a[j]、a[j+1]或a[j-1]、a[j]。
在利用数组解决问题时需要注意数组下标不要越界。
假如定义一个整形数组inta[n],则数组元素下标的取值范围是0~(n1)0~(n-1)0~(n1),下标小于或者大于n1n-1n1都视为下标越界。
如果相邻元素采用a[j]、a[j+1]表示的话,则下标取值范围是0~(n2)0~(n-2)0~(n2);
若采用a[j-1]、a[j]表示,下标取值范围则是1~(n1)1~(n-1)1~(n1)
设计二
数组元素互换也是经常遇到的一类题型,一般这种情况我们需要借助一个中间变量才可以完成,对于许多初学者来说经常犯的一个错误是:对两个元素直接相互赋值,而不借助中间变量。
我们先来看生活中的一个例子:
在蓝墨水瓶中装有蓝墨水,红墨水瓶中装有红墨水;现在我们要把蓝墨水放到红墨水瓶中,红墨水放到蓝墨水瓶中。
做法是先找一个白色空瓶(作用相当于程序中的中间变量):
首先将蓝墨水倒入白色空瓶:t=a或t=a[i+1];
接着将红墨水倒入蓝墨水瓶:a=a[i+1]或a[i+1]=a;
最后将白瓶中的蓝墨水倒入红墨水瓶:a[i+1]=t或a=t;
经过这3步就完成了红墨水与蓝墨水的互换。如果不借助白色空瓶,直接把蓝墨水倒入红墨水瓶,或把红墨水倒入蓝墨水瓶,这样必将破坏原来所存储的内容。
第一轮的交换过程可以用简单的程序段进行表示:
第二轮交换过程(最后一个元素经过第一轮比较已经确定,不需要再次进行比较):
第三轮交换过程(最后两个元素已经确定,不需要再次进行比较):
结论
由上面的程序段发现,第一轮比较的判定条件为jn-1;
第二轮为jn-2;
第三轮为jn-3;
依次类推,第i轮的循环判定条件必为jn-i。
在编程过程中我们可以用两层循环来控制,第一层循环控制交换的轮数,第二层循环控制每轮需要交换的次数。
5.流程框架
6.代码实现
假设有下面一组无序数组,我们要对它进行升序排序
完整代码