学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码!
今天是学Python的第28天,学的内容是冒泡排序。这是前面漏的一个知识点,开学了,时间不多,写得不多,见谅。
目录
[4.Python 实现冒泡排序的多种方式](#4.Python 实现冒泡排序的多种方式)
[1. 最坏情况](#1. 最坏情况)
[2. 最好情况](#2. 最好情况)
[3. 平均情况](#3. 平均情况)
[1. 小规模数据排序](#1. 小规模数据排序)
[2. 作为教学示例](#2. 作为教学示例)
[1. 时间效率低下](#1. 时间效率低下)
[2. 不适用于实时性要求高的场景](#2. 不适用于实时性要求高的场景)
1.冒泡排序简述
在计算机科学的领域中,排序算法无疑是一块基石,它们在数据处理、数据库管理、算法设计等诸多方面都发挥着至关重要的作用。冒泡排序作为其中最为基础且直观的排序算法之一,虽然在效率方面可能不如一些高级排序算法,但它却以简洁易懂的特点,成为了初学者踏入排序算法世界的绝佳入门之选。在这篇详尽的博客中,我们将对 Python 中的冒泡排序进行全方位的解读,从基本原理到代码实现,再到性能分析以及实际应用场景,力求让您对冒泡排序有一个透彻的理解。
2.冒泡排序的起源与概念
冒泡排序的历史可以追溯到早期的计算机编程时代,它是最早被发明和广泛应用的排序算法之一。其名称的由来颇具趣味性,正如我们在日常生活中看到的气泡在液体中上浮的现象一样,在待排序的数列中,较小(或较大,取决于排序规则)的元素会如同气泡般逐渐 "浮" 到数列的合适位置,故而得名冒泡排序。
从概念上讲,冒泡排序是一种基于比较和交换操作的排序算法。它的核心思想是通过反复比较相邻的元素,并在必要时交换它们的位置,从而使数列中的元素逐渐按照特定的顺序(如从小到大或从大到小)排列。
3.冒泡排序的详细工作原理
本质:让一个数字和它相邻的下一个数字进行比较运算,如果前一个数大于后一个数字,就交换两个数据的位置.
假设有一组数据,6,5,3,1,8,7,2,4
首先,从数列的第一个元素开始,依次比较相邻的两个元素。比较6和5,因为6>5,所以交换这两个元素的位置,此时数列变为 [5, 6, 3, 1, 8, 7, 2, 4]
。
接着,比较新数列中的第二个元素 6
和第三个元素 3
,由于 6 > 3
,再次交换它们的位置,得到 [5, 3, 6, 1, 8, 7, 2, 4]
。然后比较 6
和 1
,交换后变为 [5, 3, 1, 6, 8, 7, 2, 4]
。
继续比较 6
和 8
,因为 6 < 8
,所以这两个元素位置不变,数列依然是 [5, 3, 1, 6, 8, 7, 2, 4]
。再比较 8
和 7
,交换后变为 [5, 3, 1, 6, 7, 8, 2, 4]
。接着比较 8
和 2
,交换后变为 [5, 3, 1, 6, 7, 2, 8, 4]
。再比较 8
和 4
,交换后第一轮排序结束,此时数列变为 [5, 3, 1, 6, 7, 2, 4, 8]
。可以发现,经过第一轮的比较和交换操作,数列中的最大元素 8
已经 "浮" 到了数列的末尾。接下来还需要进行多轮这样的操作,才能将整个数列按照从小到大的顺序完全排好序哦。比如第二轮操作就会从数列的第一个元素开始,重复上述比较交换过程,但此时因为最大元素 8
已经在末尾了,就主要是对前面 7
个元素进行类似的处理,让第二大的元素也能 "浮" 到合适的位置,以此类推,直到整个数列有序。
4.Python 实现冒泡排序的多种方式
(1).普通版
python
nums = [6,5,3,1,8,7,2,4]
i = 0
while i < len(nums) - 1:
i += 1
n = 0
while n < len(nums) - 1:
# print(nums[n],nums[n+1])
if nums[n]> nums[n+1]:
nums[n],nums[n+1] = nums[n+1],nums[n]
n += 1
print(nums)
演示结果
(2).进阶版1
减少最后重复的判断
python
i = 0
count = 0
while i < len(nums) - 1:
n = 0
while n < len(nums) - 1 - i:
# print(nums[n],nums[n+1])
count += 1
if nums[n]> nums[n+1]:
nums[n],nums[n+1] = nums[n+1],nums[n]
n += 1
i += 1
#print(nums)
print("循环了%d次"%count)
演示结果
(3).进阶版2
加入标志位判断是否已经有序,在基本实现方式中,即使数列在排序过程中已经提前变得有序了,程序仍然会按照预定的轮数继续执行完所有的比较和交换操作。为了提高效率,我们可以加入一个标志位(flag)来判断数列是否已经有序,如果在某一轮排序中没有发生任何交换操作,就说明数列已经有序了,此时就可以提前结束排序过程。
python
count = 0
j = 0
while j < len(nums) - 1:
# 在每一趟都定义一个flag
flag = True # 假设每一趟都没有换行
i = 0
while i < len(nums) - 1 - j:
# print(nums[n],nums[n+1])
count += 1
if nums[i]> nums[i+1]:
# 只要交换了,假设就不成立
nums[i],nums[i+1] = nums[i+1],nums[i]
i += 1
if flag:
# 这一趟走完以后,flag依然是True,说明这一趟没有进行过数据交换
j += 1
print(nums)
print("循环了%d次"%count)
演示结果
5.冒泡排序的时间复杂度和空间复杂度分析
(1).时间复杂度
时间复杂度是衡量一个算法运行时间随输入规模增长而增长的趋势。对于冒泡排序来说,它的时间复杂度分析如下:
1. 最坏情况
当输入数据是逆序排列时,例如数列 [5, 4, 3, 2, 1]
要按照从小到大的顺序进行排序,每一轮排序都需要进行最多的比较和交换操作。
第一轮排序需要比较 n - 1
次(这里 n
是数列的长度),第二轮排序需要比较 n - 2
次,以此类推,最后一轮排序需要比较 1
次。
总的比较次数为:
所以,在最坏情况下,冒泡排序的时间复杂度为 ,其中 n
是要排序的数列的长度。
2. 最好情况
当输入数据已经是有序的,例如数列 [1, 2, 3, 4, 5]
要按照从小到大的顺序进行排序,每一轮排序只需要进行 n - 1
次比较操作(因为不需要进行交换),所以在最好情况下,冒泡排序的时间复杂度为 。
3. 平均情况
在实际应用中,输入数据的排列情况是随机的。对于随机排列的输入数据,平均情况下,冒泡排序的时间复杂度也趋近于 。
(2).空间复杂度
空间复杂度是衡量一个算法在运行过程中所需要的额外空间随输入规模增长而增长的趋势。
冒泡排序是一种原地排序算法,它在排序过程中只需要常数级别的额外空间来存储一些临时变量,比如在交换元素时使用的临时变量。
所以,冒泡排序的空间复杂度为 ,这意味着无论要排序的数列长度如何变化,它所需要的额外空间都是固定的。
6.冒泡排序的实际应用场景与局限性
(1).应用场景
虽然冒泡排序的效率相对较低,但在一些特定的场景下,它仍然有其应用价值。
1. 小规模数据排序
当需要排序的数据规模较小(例如,小于 100 个元素)时,冒泡排序的简单性和直观性使得它成为一个不错的选择。由于其代码实现简单,对于初学者来说容易理解和掌握,并且在小规模数据的情况下,它的运行时间也不会过长,所以可以满足一些简单的数据处理需求。
2. 作为教学示例
冒泡排序是排序算法中的经典示例,它以简洁易懂的方式展示了排序的基本原理 ------ 通过比较和交换相邻元素来实现排序。因此,在计算机科学的教学过程中,它常被用作介绍排序算法的入门示例,帮助学生理解排序算法的概念、工作原理以及如何用代码实现。
(2).局限性
然而,冒泡排序也存在一些明显的局限性。
1. 时间效率低下
如前面所分析的,冒泡排序的时间复杂度在最坏和平均情况下都是 ,这使得它在处理大规模数据时效率非常低。随着数据规模的增大,其运行时间会呈平方级增长,导致排序过程变得非常缓慢。
2. 不适用于实时性要求高的场景
由于其低效率,在那些对排序速度有较高要求的实时性场景中,如实时数据处理、高频交易等领域,冒泡排序通常不适用。在这些场景中,需要使用更高效的排序算法,如快速排序、归并排序等,来满足快速排序的需求。
总结
通过这篇博客,我们对 Python 中的冒泡排序进行了全面而深入的研究。从它的起源与概念出发,详细剖析了其工作原理和多种实现方式,包括基本实现方式、优化实现方式以及可视化实现方式。我们还深入分析了它的时间复杂度和空间复杂度,探讨了它的实际应用场景和局限性。
冒泡排序虽然是一种简单的排序算法,但它在理解排序算法的基本原理方面有着重要的作用。对于初学者来说,它是进入排序算法世界的一把钥匙;对于有一定编程经验的人来说,它也可以作为优化算法性能的一个参考对象。希望这篇博客能够帮助您更好地理解和运用冒泡排序算法,以及在合适的场景下做出正确的选择。
这是我今天学Python的自我想法和对其的理解,有不对的地方请同志们多多包涵,谢谢观看!