Python 列表示例气泡排序算法

什么是冒泡排序?

冒泡排序是一种排序算法,通过比较两个相邻的值,将列表项按升序排序。如果第一个值大于第二个值,则第一个值占据第二个值的位置,而第二个值占据第一个值的位置。如果第一个值小于第二个值,则不进行交换。

此过程将一直重复,直到列表中的所有值都被比较并根据需要进行交换。每次迭代通常称为一个“趟”。冒泡排序中的趟数等于列表中元素的数量减一。

在本篇 Python 教程中,你将学习:

实现冒泡排序算法

我们将把实现分解为三个步骤:问题、解决方案和可用于编写任何语言代码的算法。

问题

给定一个随机顺序的列表,我们希望将其按有序的方式排列。

考虑以下列表

[21,6,9,33,3]

解决方案

遍历列表,比较相邻的两个元素,如果第一个值大于第二个值,则交换它们。

结果应如下所示

[3,6,9,21,33]

算法

冒泡排序算法的工作原理如下:

第一步)获取元素总数。获取给定列表中的项总数。

第二步)确定要进行的外部趟数(n-1)。其长度是列表长度减一。

第三步)对外趟 1 执行内趟(n-1)次。获取第一个元素的值并与第二个值进行比较。如果第二个值小于第一个值,则交换位置。

第四步)重复第三步的趟数,直到达到外部趟(n-1)。获取列表中的下一个元素,然后重复第三步中执行的过程,直到所有值都已放置在正确的升序中。

第五步)所有趟都完成后返回结果。返回排序列表的结果。

第六步)优化算法

如果列表或相邻值已排序,则避免不必要的内部趟。例如,如果提供的列表已按升序排序,则可以提前终止循环。

优化的冒泡排序算法

默认情况下,Python 中的冒泡排序算法会比较列表中的所有项,而不管列表是否已排序。如果给定的列表已排序,比较所有值会浪费时间和资源。

优化冒泡排序可以帮助我们避免不必要的迭代,节省时间和资源。

例如,如果第一个和第二个项已排序,则无需遍历其余值。迭代将终止,然后开始下一个,直到完成过程,如下面的冒泡排序示例所示。

优化通过以下步骤完成:

第一步)创建一个标志变量,用于监视内部循环中是否发生了任何交换。

第二步)如果值已交换位置,则继续下一个迭代。

第三步)如果值未交换位置,则终止内部循环,并继续外部循环。

优化的冒泡排序更有效,因为它只执行必要的步骤,并跳过不需要的步骤。

可视化表示

给定一个包含五个元素的列表,下图说明了冒泡排序在排序它们时如何遍历这些值。

下图显示了未排序的列表。

Visual Representation

第一次迭代

步骤 1)

Visual Representation

比较值 21 和 6,检查哪个值更大。

Visual Representation

21 大于 6,因此 21 占据 6 的位置,而 6 占据 21 占据的位置。

Visual Representation

我们修改后的列表现在看起来像上面。

步骤 2)

Visual Representation

比较值 21 和 9。

Visual Representation

21 大于 9,因此我们交换 21 和 9 的位置。

Visual Representation

新列表现在如上。

步骤 3)

Visual Representation

比较值 21 和 33,找出较大的值。

Visual Representation

33 大于 21,因此不发生交换。

步骤 4)

Visual Representation

比较值 33 和 3,找出较大的值。

Visual Representation

33 大于 3,因此我们交换它们的位置。

Visual Representation

第一次迭代结束时排序后的列表如上。

第二次迭代

第二次迭代后的新列表如下:

Visual Representation

第三次迭代

第三次迭代后的新列表如下:

Visual Representation

第四次迭代

第四次迭代后的新列表如下:

Visual Representation

Python 示例

以下代码显示了如何在 Python 中实现冒泡排序算法。

def bubbleSort( theSeq ):
    n = len( theSeq )

    for i in range( n - 1 ) :
        flag = 0

        for j in range(n - 1) :
            
            if theSeq[j] > theSeq[j + 1] : 
                tmp = theSeq[j]
                theSeq[j] = theSeq[j + 1]
                theSeq[j + 1] = tmp
                flag = 1

        if flag == 0:
            break

    return theSeq

el = [21,6,9,33,3] 

result = bubbleSort(el)

print (result)

执行上述 Python 冒泡排序程序会产生以下结果:

[6, 9, 21, 3, 33]

代码解释

对 Python 冒泡排序程序代码的解释如下:

Code Explanation

此处,

  1. 定义一个接受参数 theSeq 的 bubbleSort 函数。代码不输出任何内容。
  2. 获取数组的长度并将值赋给变量 n。代码不输出任何内容。
  3. 启动一个 for 循环,该循环运行冒泡排序算法 (n-1) 次。这是外部循环。代码不输出任何内容。
  4. 定义一个标志变量,用于确定是否发生了交换。这是为了优化目的。代码不输出任何内容。
  5. 启动内部循环,该循环将列表中的所有值从第一个比较到最后一个。代码不输出任何内容。
  6. 使用 if 语句检查左侧的值是否大于其右侧紧邻的值。代码不输出任何内容。
  7. 如果条件求值为 true,则将 theSeq[j] 的值赋给临时变量 tmp。代码不输出任何内容。
  8. 将 theSeq[j + 1] 的值赋给 theSeq[j] 的位置。代码不输出任何内容。
  9. 将变量 tmp 的值赋给 theSeq[j + 1] 的位置。代码不输出任何内容。
  10. 将标志变量赋值为 1,表示已发生交换。代码不输出任何内容。
  11. 使用 if 语句检查变量 flag 的值是否为 0。代码不输出任何内容。
  12. 如果值为 0,则调用 break 语句退出内部循环。
  13. 返回已排序的 theSeq 值。代码输出排序后的列表。
  14. 定义一个变量 el,其中包含一个随机数列表。代码不输出任何内容。
  15. 将 bubbleSort 函数的值赋给变量 result。
  16. 打印变量 result 的值。

冒泡排序的优点

以下是冒泡排序算法的一些优点:

  • 易于理解。
  • 当列表已排序或几乎排序时,它表现非常好。
  • 它不需要大量的内存。
  • 编写算法代码很容易。
  • 与其他排序算法相比,空间要求极小。

冒泡排序的缺点

冒泡排序算法的一些缺点如下:

  • 在排序大型列表时,其表现不佳。它需要大量的时间和资源。
  • 它主要用于学术目的,而非实际应用。
  • 对列表进行排序所需的步数约为 n2

冒泡排序的复杂度分析

有三种类型的复杂度:

1)排序复杂度

排序复杂度用于表示对列表进行排序所需的执行时间和空间量。冒泡排序需要 (n-1) 次迭代来对列表进行排序,其中 n 是列表中元素的总数。

2)时间复杂度

冒泡排序的时间复杂度为 O(n2)。

时间复杂度可分为:

  • 最坏情况:列表按降序提供。算法执行最大次数的执行,表示为 [大 O] O(n2)。
  • 最佳情况:当提供的列表已排序时,这种情况发生。算法执行最少次数的执行,表示为 [大 Ω] Ω(n)。
  • 平均情况:当列表为随机顺序时,这种情况发生。平均复杂度表示为 [大 θ] ⊝(n2)。

3)空间复杂度

空间复杂度衡量了对列表进行排序所需的额外空间量。冒泡排序仅需要一个额外的空间用于交换值的临时变量。因此,其空间复杂度为 O(1)。

摘要

  • 冒泡排序算法通过比较两个相邻的值,如果左边的值小于右边的值,则交换它们。
  • 使用 Python 实现冒泡排序算法相对简单。您只需要使用 for 循环和 if 语句。
  • 冒泡排序算法解决的问题是将一个随机列表项转换为一个有序列表。
  • 当列表已排序时,数据结构中的冒泡排序算法表现最佳,因为它执行的迭代次数最少。
  • 当列表顺序颠倒时,冒泡排序算法的表现不佳。
  • 冒泡排序的时间复杂度为 O(n2),空间复杂度为 O(1)。
  • 冒泡排序算法最适合学术目的,不适合实际应用。
  • 优化的冒泡排序通过跳过对已排序值的检查,从而提高了算法的效率。