先用一个简单的例子来说明一下冒泡排序的过程。
假如待排序的数组为|5|4|3|2|1|,我们需要按照从小到大的顺序将这个数组进行排序,那么使用冒泡排序的步骤如下所示:
第一轮:
原:|5|4|3|2|1|
1)|4|5|3|2|1|
5比4大,交换位置
2)|4|3|5|2|1|
5比3大,交换位置
3)|4|3|2|5|1|
5比2大,交换位置
4)|4|3|2|1|5|
5比1大,交换位置
经过第一轮交换,数组中的最大元素,即5,放置在了正确的位置上
用文字来说明就是,第一个和第二个元素比较,如果第一个元素大于第二个元素则交换位置,接着第二个元素和第三个元素比较,如果第二个元素大于第三个元素则交换位置,以此类推…每一轮都会有一个元素(未排序数组中的最大值)放置在正确的位置上。
对于5个元素的数组一共需要4轮的交换,则数组就排好序了。
下面用C++来实现冒泡排序:
template<typename T>
void bubbleSort1( T arr[], int n ){
for( int i = 0; i < n; i ++ ){
for( int j = 0; j < n - i - 1; j ++ ){
if( arr[j] > arr[j + 1] )
swap( arr[j], arr[j + 1] );
}
}
}
从上面的代码中也可以看出来,冒泡排序是一种时间复杂度为O(n^2)的算法。这个排序算法还有可以改进的地方,上述的代码,无论整个数组是否一开始就有序了,都会执行n-1轮的冒泡,例如如果待排序数组是|1|2|3|4|5|,这个数组本来已经有序,但是使用上述算法还是会进行4轮冒泡。对于这个问题,我们可以使用一个标志位来解决,只要在第二层循环中没有发生过数据交换,则说明数组已经有序,就不需要继续进行下去了。代码如下所示:
template<typename T>
void bubbleSort2( T arr[], int n ){
bool ischanged = false;
for( int i = 0; i < n; i ++ ){
for( int j = 0; j < n - i - 1; j ++ ){
if( arr[j] > arr[j + 1] ){
swap( arr[j], arr[j + 1] );
ischanged = true;
}
}
if( !ischanged )
return;
}
}
冒泡排序虽然简单,但它也是排序算法的基础,面试中偶尔也会问到,所以还是有必要复习一下。