程序员在程序设计时常常需要对存储在数组中的大量数据进行处理,如排序、查找等。排序是把一系列无序的数据按照特定的顺序(如升序或降序)重新排列为有序序列的过程。对数据进行排序是最重要的应用之一。实际生活中的很多问题都需要对数据进行排序。这次我们来介绍一种排序方法:冒泡排序法。
首先我们来看冒泡排序法的原理:重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻元素可以交换,就表明完成了排序。
让我们来拆解以下冒泡排序法的过程。首先重复扫描待排序序列,就需要用到循环语句,而比较每一对相邻的元素,当该对元素顺序不正确时进行交换,就需要用到if语句并使用交换算法。
举个例子:初始待排序数据为28 32 14 12 53 42,假如我们以升序对这组数据进行排列,第一对相邻元素为28 32,由于28<32,故顺序正确,保持位置不动。第二对相邻元素为32 14,因32>14,故32应与14交换位置,得到新序列:28 14 32 12 53 42。此时第三对相邻元素变为32 12,再次交换,使序列变为28 14 12 32 53 42……一直到最大的数53排到最后一位,那么我们就得到一个经过一轮排序的序列:28 14 12 32 42 53。
可以发现,在冒泡排序法的过程中,最大的数(最小的数)在一次次的交换中逐渐浮现到序列的最后面,就像泡泡一样,逐渐冒出水面,因此其有个形象的名字,即冒泡排序法。但我们发现,仅经过一轮比较是无法对序列排序完全的,因此需要多加一个循环来控制比较的轮数。于是我们有一个循环控制相邻元素对的变换,另一个循环控制比较的轮数。
此算法可以依靠如下代码实现:
int array[n] = {...};//假设n为常量
for (int i=0; i<n-1; i++)//控制比较的轮数,n个数只需n-1轮比较
{
for (int j=0; j<n-1-i; j++)//控制相邻对元素变换,n个数有n-1对相邻元素,因每一轮比较可排好一个数的顺序,故每一轮比较后都减去已排好的数,得到新的需要排序的数
{
if (array[j]>array[j+1])
{
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
实际效果如下:
同理,当降序排列时,只需把if中条件改为array[j] < array[j+1]。
由此可见,每n个数需要n-1轮比较,每比较1次减少1个需排序的数,故一共需要次比较,但若经过若干轮循环后,我们要排列的数已是有序序列,那么此时接下类的比较操作已是无用功。为了减少比较的次数,我们可以增加一个标志变量,当已排成有序序列时即跳出循环,以优化算法。