冒泡排序是最简单的排序算法,每次扫描一趟数组,比较相邻元素,若逆序则交换,第一次确定最后一个位置的元素,以此类推直至所有元素按顺序排列。
因此,最直接的思路是对长度为n的数组扫描n-1,代码实现如下:
void bubblesortA(int A[], int n)
{
for (int i = n-1;i > 0;i--)
{
for (int j = 0;j < i;j++)
{
if (A[j] > A[j + 1])
swap(A[j], A[j + 1]);
}
}
}
由代码可以分析得到,最坏的情况,时间复杂度为o(
n2
)
但是,很多情况下,当我们扫描完m次(
m<<n
)时,数组已经有序,这时我们希望可以提前中止,因此,我们将上述代码改进为以下形式:
void bubblesortB(int A[], int n)
{
for (int i = n - 1;i > 0;i--)
{
int sort = true;
for (int j = 0;j < i;j++)
{
if (A[j] > A[j + 1])
{
sort = false;
swap(A[j], A[j + 1]);
}
}
if (sort)
break;
}
}
但是,这还不够,实际应用中,还存在着一种情况,即数组后半部分已经有序,只有前半部分无序,此时,我们将不再比较数组的后半部分,仅对前半部分重新排序,具体的代码实现如下:
void bubblesortC(int A[], int n)
{
for (int i = n - 1;i > 0;)
{
int last = i;
int sort = true;
for (int j = 0;j < i;j++)
{
if (A[j] > A[j + 1])
{
sort = false;
swap(A[j], A[j + 1]);
last = j;
}
}
i = last;
if (sort)
break;
}
}
尽管做了如上优化,冒泡排序始终是时间复杂度为o( n2 )的算法,但是冒泡排序稳定,即若数组中出现两个或多个相同的元素,排序后的数组中,相同元素的相对位置与排序前一致。