文章目录
- 1. 什么是冒泡排序
- 2. 程序实现原理
- 3. Python 代码实现(低级版本)
- 4. Python 代码实现(高级版本)
1. 什么是冒泡排序
冒泡排序是把一个由同类型元素组成的序列(如数字组成的列表)中的元素按照一定顺序(升序或者降序)依次排列的方法。
实现方式是将序列的第一对(可以使倒数第一对,也可以正数第一对,自己根据需要定义)元素进行比较,决定较大的放在左边(降序排列)或者右边(升序排列),然后依次进行第二对元素的比较,然后根据大小决定是否交换位置,依次类推,如果按照升序排列,那么最后一个数就是最大数。
下图将数列[1,5,2,3,4]
进行升序排序,详细过程如下:
2. 程序实现原理
- 通过等差数列求和公式计算需要循环多少次。
- 设置变量用于定位元素索引位置,该变量可以实现自加1
- 通过if/elif/else 判断是否交换位置、判断是否完成某个新数列的排序、恢复位置索引
- 完成排序,打印新数列
一定要理解上图中所讲的新数列是什么意思,后文将用到新数列的说法
伪代码如下:
序列为 = [1,5,2,3,4]
索引1 用于定位一对数的前者 = 0
索引2 用于定位一对数的后者 = 1
索引3 用户定位新数列需要比较的元素= 1
需要执行的循环次数 = (4*(1+4))/2=10
for _ in range(10+序列元素数量-2): 本来应该用for循环10次,但是在下面的if判断中,会由于索引越界浪费(元素数量-1(也就是新数列个数))次机会再排除最后一次越界,所以10+序列元素数量-1-1
if (序列索引1的元素 <= 序列索引2的元素) 且 序列索引2 <= 序列最大索引(元素个数-索引3):
什么也不做,因为左边元素不大于右边元素,但是这次索引变量要自加1,进行下一对元素的比较
索引1 += 1
索引2 += 1
elif (序列索引1的元素 > 序列索引2的元素) 且 序列索引2 <= 序列最大索引(元素个数-索引3):
序列索引1的元素 和 序列索引2的元素 交换位置
索引1 += 1
索引2 += 1
else:执行到这一步 就说明已经完成某个序列中最大数的排序,恢复索引默认值对新数列进行排序
索引1 = 0
索引2 = 0
索引3 += 1 新数列最后一位数不用进行排序,因为已经完成了
最后打印排序完成的序列
3. Python 代码实现(低级版本)
基于以上实现原理,用python代码实现如下:
nums=[1,5,2,4,3]
index1 = 0
index2 = 1
index3 = 1
times = 1 # 用于打印标记运行次数,可有可无,不影响功
sum_count = ((len(nums)-1)*(1+len(nums)-1))//2 # 等差数列求和公式
print("数列 {0:},共 {1:} 个元素,需要进行 {2:} 次排序,过程中将对 {3:} 个新数列排序\n".format(nums,len(nums),sum_count,len(nums)-1))
for _ in range(sum_count+len(nums)-1): #用for循环xx次
if index2<=len(nums)-index3 and nums[index1] <= nums[index2] :
print("Seq {0:}:".format(times),nums[index1],"--->",nums[index2],":不换位","--> 新数列为 {0:}".format(nums))
index1 += 1
index2 += 1
times += 1
elif index2<=len(nums)-index3 and nums[index1] > nums[index2]:
nums[index1],nums[index2] = nums[index2],nums[index1]
print("Seq {0:}:".format(times),nums[index2],"--->",nums[index1],":换位","--> 新数列为 {0:}".format(nums))
index1 += 1
index2 += 1
times += 1
else:
print("Seq {0:}: 完成对元素 {1:} 的排序,接下来对数列 {2:} 排序".format(times-1,nums[len(nums)-index3],nums[:len(nums)-index3]))
index1 = 0
index2 = 1
index3 += 1
print("数列升序排列后为: ",nums)
运行结果如下:
数列 [1, 5, 2, 4, 3],共 5 个元素,需要进行 10 次排序,过程中将对 4 个新数列排序
Seq 1: 1 ---> 5 :不换位 --> 新数列为 [1, 5, 2, 4, 3]
Seq 2: 5 ---> 2 :换位 --> 新数列为 [1, 2, 5, 4, 3]
Seq 3: 5 ---> 4 :换位 --> 新数列为 [1, 2, 4, 5, 3]
Seq 4: 5 ---> 3 :换位 --> 新数列为 [1, 2, 4, 3, 5]
Seq 4: 完成对元素 5 的排序,接下来对数列 [1, 2, 4, 3] 排序
Seq 5: 1 ---> 2 :不换位 --> 新数列为 [1, 2, 4, 3, 5]
Seq 6: 2 ---> 4 :不换位 --> 新数列为 [1, 2, 4, 3, 5]
Seq 7: 4 ---> 3 :换位 --> 新数列为 [1, 2, 3, 4, 5]
Seq 7: 完成对元素 4 的排序,接下来对数列 [1, 2, 3] 排序
Seq 8: 1 ---> 2 :不换位 --> 新数列为 [1, 2, 3, 4, 5]
Seq 9: 2 ---> 3 :不换位 --> 新数列为 [1, 2, 3, 4, 5]
Seq 9: 完成对元素 3 的排序,接下来对数列 [1, 2] 排序
Seq 10: 1 ---> 2 :不换位 --> 新数列为 [1, 2, 3, 4, 5]
Seq 10: 完成对元素 2 的排序,接下来对数列 [1] 排序
数列升序排列后为: [1, 2, 3, 4, 5]
4. Python 代码实现(高级版本)
用for迭代实现冒泡排序,代码简单,逻辑性强:
import random,datetime
nums =[random.randint(0,1000) for _ in range (150) ] #生成150个随机0-1000范围内的随机整数组成的列表,用于排序
for i in range(len(nums) - 1): # 这个循环负责设置冒泡排序进行的次数,也就是新数列的个数
for j in range(len(nums) - i - 1): # 对每个新数列进行排序
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
print(nums)
该代码的运算速度是基本版本的2.5倍。