算法原理
基本思想是逐个比较相邻数据,如果前面数据大于后面数据,则进行交换,一轮比较结束后,最大数浮出至最后(形成有序队列)。循环处理无序队列,直至全部有序。
20 34 19 4 33 59 90 18
20 19 4 33 34 59 18 90
19 4 20 33 34 18 59 90
4 19 20 33 18 34 59 90
4 19 20 18 33 34 59 90
4 19 18 20 33 34 59 90
4 18 19 20 33 34 59 90
4 18 19 20 33 34 59 90
上述示例是冒泡排序的简单过程,蓝色字体区域是不停遍历之后产生的有序队列,黑色字体区域是未排序的无序队列,每一轮都产生当前无序队列中的最大值,并进入有序队列。
算法分析
冒泡排序中主要包含关键字比较C和交换操作S。
最优情况:
4 18 19 20 33 34 59 90
本身序列是有序的:
比较次数C = (n -1) + (n - 2) + … + 1 = n*(n - 1)/2
交换次数S = 0
最坏情况
90 59 34 33 20 19 18 4
本身序列是反序的:
比较次数C = (n -1) + (n - 2) + … + 1 = n*(n - 1)/2
交换次数S = (n -1) + (n - 2) + … + 1 = n*(n - 1)/2
时间复杂性
未作优化情况下,冒泡排序需要比较所有数据,时间复杂度都是O(n^2)。
空间复杂性
冒泡排序不需要临时存储空间,所以空间复杂度是O(1)。
算法稳定性
冒泡排序算法中是将大的数据进行交换,如果两个相邻数据是相等的,不会进行交换,所以冒泡排序是稳定的。
算法实现
void bubbleSort(int arr[], int nLen)
{
for (int i = 0; i < nLen; i++)
{
for (int j = 0; j < nLen - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
std::swap(arr[j], arr[j+1]);
}
}
}
}
算法优化
冒泡排序主要包含了比较和交换操作,比较操作不区分场合,都需要比较所有数据,所以在最优的情况下复杂度也达到了O(n^2)。
当一遍轮询后未发生交换操作,说明序列本身已经有序的,排序完成。此种情况下,最优情况下在一次遍历后即完成整个排序,时间复杂度可以优化至O(n)。