BubbleSort 冒泡排序

问题

用Bubble Sort对长度为nn的无序序列ss从小到大(升序)排序。

解法

将长度为nn的序列s=[x0,x1,,xn1]s = [x_0, x_1, \dots, x_{n-1}]分为左右两个部分,未排序的left=[x0,,xk]left = [x_0, \dots, x_k]和已排序的right=[xk+1,,xn1]right = [x_{k+1}, \dots, x_{n-1}],其中0kn10 \le k \le n-1。如图:

初始时left=[x0,,xn1],right=left = [x_0, \dots, x_{n-1}], right = \varnothing。如图:

leftleft做如下操作:

function Bubble(s, k):
    for i = [0, k]
        if s[i] > s[i+1]
            swap(s[i], s[i+1])

(1) Bubble函数第2行:从左向右遍历leftleft中的所有元素s[i]s[i]

(2) Bubble函数第3-4行:比较s[i]s[i]s[i+1]s[i+1],若s[i]>s[i+1]s[i] \gt s[i+1]则交换两个元素,否则不做任何操作。这样一次操作会将leftleft中的最大元素移动到最右边,下一次调用Bubble函数时,只需要将输入参数kk变为k1k - 1,就可以将上一次leftleft最右边的元素加入rightright的最左边;

上述操作如图:

运行一次Bubble函数可以将leftleft中最大的元素移动到rightright最左边(leftleft长度减1,rightright长度加1)。初始时leftleft长度为nnrightright长度为00,只需重复调用nn次Bubble函数即可完成排序:

function BubbleSort(s, n):
    for k = [n-1, 0]
        Bubble(s, k)

例如对于下图中的数组ssleftlefts[0,5]s[0,5]rightrights[6,n1]s[6,n-1]。从i=0i = 0开始向右遍历,依次比较s[i]s[i]s[i+1]s[i+1],若s[i]>s[i+1]s[i] \gt s[i+1]则交换两个元素,直到i=5i = 5

\cdots

然后将leftleft中的最大值s[5]=57s[5] = 57合并到rightright部分中,再进行新一轮的遍历交换操作。

每次遍历都可以筛选出leftleft中最大的元素,重复nn次即可对整个数组完成排序,算法结束。

复杂度

Bubble函数的输入规模为T(k)T(k),遍历kk个元素的时间复杂度为O(k)O(k),判断两个元素的大小、交换两元素的值的时间复杂度为O(1)O(1),该操作的时间复杂度为:

T(k)=O(k)+O(1)=O(k)\begin{matrix} T(k) & = & O(k) + O(1) \\ & = & O(k) \end{matrix}

BubbleSort函数的输入规模为T(n)T(n),循环调用nn次Bubble函数,时间复杂度为O(n)O(n),调用Bubble的平均输入规模为T(n)T(n),该操作的时间复杂度为:

T(n)=O(n)O(n)=O(n2)\begin{matrix} T(n) & = & O(n) \cdot O(n) \\ & = & O(n^2) \end{matrix}

该算法的时间复杂度为O(n2)O(n^2)。该算法没有额外占用内存(没有动态分配内存),空间复杂度为为O(1)O(1)

源码

BubbleSort.h

BubbleSort.cpp

测试

BubbleSortTest.cpp

Last updated