在很多地方看到冒泡排序的最佳时间复杂度是O(n),即在序列本来就是正序的情况下。但是最开始一直是怀疑和疑惑的。
因为如果根据下面的代码按照《算法导论》上对插入排序时间复杂度的计算和分析,即使数组本身为正序,循环的执行次数并没有减少,只是没有进行交换操作,得出时间复杂度依然是O(n^2)的结论并没有感觉有问题。
public void bubbleSort(int arr[]) {
for(int i = 0, len = arr.length; i < len - 1; i++) {
for(int j = 0; j < len - i - 1; j++) {
if(arr[j + 1] < arr[j])
swap(arr, j, j + 1);
}
}
}
后来查了资料,才发现是在数组正序情况下,算法代码需要优化,才达到最佳情况的时间复杂度是O(n)。代码如下:
public void bubbleSort(int arr[]) {
boolean didSwap;
for(int i = 0, len = arr.length; i < len - 1; i++) {
didSwap = false;
for(int j = 0; j < len - i - 1; j++) {
if(arr[j + 1] < arr[j]) {
swap(arr, j, j + 1);
didSwap = true;
}
}
if(didSwap == false)
return;
}
}
加入了交换标志didSwap,i=0第一遍遍历,进行n-1次比较,因为数组本身正序不会进行任何一次交换,那么第一遍遍历完交换标志didSwap依然为false,算法直接返回结束。
只进行一次遍历,n-1次比较,算法就结束,显然冒泡排序最佳情况的时间复杂度是O(n)。