冒泡排序(Bubble Sort)见名知意,就是从前至后依次比较相邻的两个数据的大小,将大的往后移动,这样经过一次完整的比较和移动,就可以将序列中最大的一个数放置到序列的最后,这也就是它名字的由来,就像水里的水泡一样, 越往上浮越大。
算法过程:
- 比较相邻的元素,如果第一个比第二个大,就交换两个的位置。
- 从序列的开头一直到结尾一直重复这样的工作,这样一趟结束够就可以将最大的数放置到最后。
- 进行第二趟排序,但最后一个数不需要参与计较,因为它已经是最大的。
- 针对每次越来越少的数据进行N趟这样的重复操作,整个序列有序。
如下图所示,蓝色框表示没有发生交换,红色框表示发生交换。
基于这样的思想,可以写出如下代码:
void BubbleSort(int* array,int size)
{
for(int i = 0;i < size;++i)
{
for(int j = 0;j < size - i;++j)//每经过一次排序,最后一位已经最大,不需要再排
{
if(array[j] > array[j+1])
swap(array[j],array[j+1]);
}
}
}
优化:
如果一个待排序列经过较少次的比较和移动已经有序呢?
0 1 2 3 4 5 6 7 9 8 //一次排序交换9和8就已经有序,但还是要进行n(n -1)/2次比较,就显得做无用功了。
冒泡排序中,如果一趟完整的比较中没有数据之间的交换,那么序列一定是已经有序了,不需要再进行之后的比较了。可以定义一个变量flag,来标记是否发生交换,如果没有交换,就直接退出程序了。
如下:
void BubbleSort1(int* array, int size)
{
assert(array);
bool Flag = false;
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size - i; ++j)
{
if (array[j] > array[j + 1])
swap(array[j], array[j + 1]);
Flag = true;
}
if (!Flag)
break;
}
}
时间复杂度:
冒泡排序一共要进行n趟排序过程,然后第一趟比较n个数据,第二趟n-1,以此类推。
所以一共进行了n(n-1)/2,即n²+n/2次,故时间复杂度为O(n²)。