开发者学堂课程【Python入门 2020年版:冒泡排序(难点非重点)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10297
冒泡排序(难点非重点)
内容介绍
一、图例讲解
二、思路讲解(11-冒泡排序)
三、代码实现(11-冒泡排序)
四、优化相关
五、总结
一、图例讲解
1.第一趟
冒泡排序属于难点但非重点,目的是为了培养大家编程思维。
如图,获得一组无序数据6 5 3 1 8 7 2 4,此时要将其变成一组有序数据,排序方法繁多,其中冒泡排序空间复杂度较大,其中心思想:让一个数字和它相邻的下一个数字进行比较运算,如果前一个数字大于后一个数字,交换两个数据的位置。
第一次排序,6和5两个数进行比较,根据如果前一个数字大于后一个数字,交换两个数据的位置。其中6比5大,所以交换两者位置。
6下标变为1。
下标0和1两数比较完成之后,6和相邻的3再次比较,6比3大,交换两者位置。6下标变为2。
之后,6再和1进行比较,6大于1故两者交换位置,6下标变为3。
最后直到6与8进行比较,前一个数6不大于后一个数8,因而6不再变化。8再继续和下一个数7进行比较,显然前一个数8大于后一个数7,两者交换位置,因而此时6下标为3,不再进行比较。8下标为5。
8继续和2进行比较,前一个树8大于后一个数2,两者交换位置,8下标为6。
最后,前一个数8与后一个数4比较,8大于4,两者交换。8最后下标为7。比较完成之后我们可以发现,最大的数移至最后。
2.总结:
冒泡排序的精髓就是,前一个数与后一个数相比,大的数向后移(冒泡),不断重复此步骤,直至排序成功。
二、思路讲解(11-冒泡排序)
1.确定内部循环次数
nums = [6,5,3,1,8
,7,2,4]
#冒泡排序思想:
#让一个数字和它相邻的下一个数字进行比较运算
#nums[0] nums [1]
#nums[ 1] nums[2]
//图例所表达的代码思想好比 nums 的第一个数和第二个数比较,第二个数再和第三个数比较,比较完成假设第一个数大于第二个数就交换位置。
…… ……
#n的取值应该是 length-2
#nums[ n] nums[n+ 1]
#…… ……
#最后一次比较,length 表示长度
nums[ length - 2] nums[leng - 1]
#该次比较没有意义,直到 length-1就是最后一次比较
#nums[ length - 1] nums[length]
总结:
nums[ length - 1] 和nums[length]之间不必比较,n 的取值到 length-2即可,因为 n 为 length -1时所对应的就是最后一个数
即 nums[ length - 2] nums[leng - 1]对应的就是 nums 里的2和4。
2.判断是否完成相邻两数互相比较
nums = [6,5,3,1,8,7,2,4]
n = 0
//len(nums)表示 nums 的长度 While n<nums 的长度-1即 n 取 length-2,注意并非-2,小于表示取不到值,len(nums) - 2时,n 取不到 len(nums) - 2
while n <len(nums) - 1:
print(nums[n],nums(n + 1))
n += 1
输出结果:
//由输出结果可以知道上述代码完成相邻两数互相比较
6 5//n=0 和n=1进行比较
5 3 //n=1 和n=2进行比较
3 1 //之后依次比较
1 8
8 7
7 2
2 4
3.第一趟排序代码实现
nums = [6,5,3,1,8
,7,2,4]
n = 0
while n <len(nums) - 1:
if nums [n] > nums [n+1]
//如果前一个数据大于后一个数据
nums[n]
,nums[n + 1] = nums[n + 1] , nums[n]
//交换位置
n += 1
print(nums)
输出结果:
[5,3,1,6,7,2,4,8] //结果与第一趟比较结果相同
三、代码实现(11-冒泡排序)
但此时认为变成有序排列,根据第一趟排序的思想,只需要不断重复循环排列数据的操作,即可变成有序。但一次次重复书写太过繁琐,因而再加上一层外部循环即可。
1.多个单次循环--淘汰版
nums = [6,5,3,1,8
,7,2,4]
while n <len(nums) - 1:
if nums [n] > nums [n+1]
//如果前一个数据大于后一个数据
nums[n]
,nums[n + 1] = nums[n + 1] , nums[n]
//交换位置
n += 1
print(nums)
while n <len(nums) - 1:
if nums [n] > nums [n+1]
//如果前一个数据大于后一个数据
nums[n]
,nums[n + 1] = nums[n + 1] , nums[n]
//交换位置
n += 1
print(nums)
while n <len(nums) - 1:
if nums [n] > nums [n+1]
//如果前一个数据大于后一个数据
nums[n]
,nums[n + 1] = nums[n + 1] , nums[n]
//交换位置
n += 1
print(nums)
…………………………
输出结果:
[5,3,1,6,7,2,4,8]
[3,1,5,6,2,4,7,8]
[1,3,5,2,4,6,7,8]
2.冒泡排序--最终代码
在此最佳循环次数7次即可,因为共有8个数字,每次比较都会得到当前数字更大的数,循环7次后,就会拿到7个最大数字,剩下的就是最小的数,不必再做比较。
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:
if nums [n] > nums [n+1]
//如果前一个数据大于后一个数据
nums[n]
,nums[n + 1] = nums[n + 1] , nums[n]
//交换位置
n += 1
print(nums)
输出结果:
[5,3,1,6,7,2,4,8] //拿出最大数8
[3,1,5,6,2,4,7,8] //拿出最大数7
[1,3,5,2,4,6,7,8] //拿出最大数6
[1,3,2,4,5,6,7,8] //拿出最大数5
[1,2,3,4,5,6,7,8] //拿出最大数4
[1,2,3,4,5,6,7,8] //拿出最大数3
[1,2,3,4,5,6,7,8] //拿出最大数2
四、优化相关
1.每一趟比较次数的优化
在第二趟的比较之中,7和之前的数一一比较,知道与最后与8比较时,其实并没有必要,因为在第一趟就已经定下了8的位置。但我们的代码每次都做了重复的比较。
2.总比较趟数的优化
同时在第五趟比较完成后,此时数组就已经是有序排列,同时在第六趟中并不存在任何的数据交换,但第七趟还在不停的做重复的比较排序。由此存在优化的地方。
3.解决方法
(1)将内部循环的 while n<len(nums) - 1变为 while n<len(nums) - 1+i
(2)可以设置标识符,发现没有交换时就停止。
4.类似于矩阵乘法表
i = 0
While i < len(nums) - 1:
i+=0
n=0
while n <len(nums) - 1:
n += 1
print(‘*’,end=’ ’)
print()
输出结果:
5. 九九乘法表(倒)
i = 0
While i < len(nums) - 1:
i+=0
n=0
while n <len(nums) - 1-i:
//加上减i就变成了倒的99乘法表
n += 1
print(‘*’,end=’ ’)
print()
输出结果:
五、总结:
冒泡排序的内层是将一个数和下一个数进行比较,即 nums[n]和 nums[n+1]进行比较,如果前一个大于后一个,交换位置。同时不止比较一趟,每一趟比较都会找到一个最大数,所以要比较 len(nums)-1趟。8个数比较7趟,10个数比较9趟。