冒泡排序优化 | 学习笔记

简介: 快速学习 冒泡排序优化

开发者学堂课程【Python入门 2020年版冒泡排序优化】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/639/detail/10301


冒泡排序优化


内容介绍

一、练习题讲解

二、冒泡排序优化


一、练习题讲解

课后题一

#有一个列表 names,保存了一组姓名 names=[ " zhangsan ' , ' lisi ' , ' chris ' , ' jerry ' , 'henry ' ]

#再让用户输入一个姓名,如果这个姓名在列表里存在,提示用户姓名已存在;

#如果这个姓名在列表里不存在,就将这个姓名添加到列表里。

答案:

1.使用 in 运算符

names=[ 'zhangsan ' , ' lisi ' , ' chris ' , ' jerry ' , 'henry ' ]

//列出列表中的元素

username = input ( ‘ 请输入一个用户名: )

//提示输入用户名,赋给变量 username

if username in names: //如果 username names

print(‘用户名已经存在’)//显示已经存在

else:  //如果不在

names.append(username)

//将输入的 username 加进列表中去

2. 使用遍历

l  错误写法

names=[ ' zhangsan ' , ' lisi ' , ' chris ' , ' jerry ' , 'henry ' ]

//列出列表中的元素

username = input ( ‘ 请输入一个用户名: )

for name in names:

if username == name

print(‘用户名已经存在’)

break

else:     //else if 对齐会使得,执行了 if 就随之执行 else

names.append(username)   //就会错误的添加多余数据

print(names)

此时不能将 else if 相对应,因为当输入 lis i时,处于第一次循环,输出的元素是与第一个元素 zhangsan 进行比较的,在 if 判断时两者不相等,若写成当前的 else 格式则会把 lisi 加进列表中,但其实列表中下一次循环含有 lisi

所以我们应该改成 for else 相对。变为当 for 循环退出之后,再执行 else

正确写法(else for 对齐)

names=[ ' zhangsan ' , ' lisi ' , ' chris ' , ' jerry ' , 'henry ' ]

//列出列表中的元素

username = input ( ‘ 请输入一个用户名: )

//提示输入用户名,赋给变量 username

for name in names:  //遍历列表中的每个元素

if username == name      //如果输入的值存在

print(‘用户名已经存在’)  //提示已存在

break            //退出循环

else:            //循环结束之后,如果都不存在

names.append(username)

/则把当前输入的 username 元素加入列表中

print(names)  //输出查看最后列表中含有的元素

else for 对齐,会等待循环结束,输入的元素被一一与列表中元素判断后,再选择是否加入元素。如输入 lisi,会提示用户已经存在,而输入 jack 则会将其加入到列表中。

输出[ ' zhangsan ' , ' lisi ' , ' chris ' , ' jerry ' , 'henry ' ,'jack']


二、冒泡排序优化

首先定义一组列表数据,现要对数据进行排序,根据冒泡排序的核心思想,将当前数不断和下一个数进行比较。

我们写一个 while 循环,循环次数为 len(nums)-1,因为在比较中我们最多可以取到倒数第二个数进行比较,因为最后一个数没有下一个数可以比较。再使用 if nums [i] > nums [i+1] 判断前一个数和后一个数之间的大小,

如果前一个数大于后一个数,交换两者位置。到此就完成了一次循环。但我们需要比较多趟,所以再添加一个循环。循环次数为同为 en(nums) - 1。到此输出结果就变为有序。

代码

#冒泡完善

nums = [6,5,3,1,8,7,2,4]

j= 0

while i < len(nums) - 1:

j += 1

i = 0

while n <len(nums) - 1:

//如果前一个数据大于后一个数据

count += 1

if nums [i] > nums [i+1]

//交换位置

nums[i]nums[i + 1] = nums[i + 1] , nums[i]

i += 1

print(nums) //输出排序后的列表

print(‘比较了%d次’ % count)//比较次数,复杂度为o(n-1)的平方

输出结果

[12345678]

比较了49

至此共比较了49次,因为列表共有8个数,每趟比较7次,共比较7趟,所以为7*7=49次。复杂度为 o(n-1)的平方,如n=8,则49次。其中也有许多重复比较的过程。

1.png

1.优化每一趟比较次数

如在第一趟中,是每个元素都互相比较,比较8次。

1.png

但在第二趟比较时,531比较时交换,但在与67比不交换。

74比时交换,但最后78其实并没有比较的意义。因为冒泡排序每一趟都是找到一个最大数,第一趟就已经找到了最大数8在末尾。所以我们可以将其删减优化。

1.png

1.png

依次类推在第三趟时,最后678都无需比较。

1.png

总结:每次多比较的次数就是j的值。

#第一趟比较时,j=0,多比较了0

#第二趟比较时,j=1,多比较了1

#第三趟比较时,j=2,多比较了2

代码

nums = [6,5,3,1,8,7,2,4]

count = 0

j= 0

#第一趟比较时,j=0,多比较了0

#第二趟比较时,j=1,多比较了1

#第三趟比较时,j=2,多比较了2

while i < len(nums) - 1:

i = 0

while n <len(nums) - 1-j:  //在每次比较时减去多余的次数j

count += 1

if nums [] > nums [i+1]

nums[i]nums[i + 1] = nums[i + 1] , nums[i]

i += 1

//要将 j+=1写在末尾,否则初始值就变为了1,在减次数时就会多减

j += 1

print(nums)

print(‘比较了%d’ %count)

输出结果

[12345678]

比较了28

代码中j为比较的趟数,i为比较的次数,所以要减少每趟多余比较的次数,只需要将次数变为<len(nums) -1 -j,同时将j+=1放在最后即可;此时第一次比较就会变为7趟,第二次比较就会变为6趟,依次递减。优化之后复杂度变为2/n(n-1),总比较次数变为28次。

2.优化总比较趟数

但在第六趟的比较过程中,列表的值已变为有序的。但仍在重复进行比较。同理此后的第七次根本没有必要执行。

1.png

所以我们可以对总比较趟数进行优化,在每一趟之后定义一个 flag,设置其初始值为 True 假设每一趟都没有换行,同时在一趟比较之后,falg 依然为 True,说明本趟没有进行数据的交换,那么就执行 break 退出循环。

最后优化结果变为比较27次,因为当第六趟发现数据不在进行交换时,就退出了循环。最后的第七趟没有再比较。

代码

nums = [6,5,3,1,8,7,2,4]

count = 0

j= 0

#第一趟比较时,j=0,多比较了0

#第二趟比较时,j=1,多比较了1

#第三趟比较时,j=2,多比较了2

while i < len(nums) - 1:

#在每一趟里都定义一个 flag

flag=True #假设每一趟都没有换行

i = 0

while n <len(nums) - 1-j:

count += 1

if nums [i] > nums [i+1]

#只要交换了,说明 flag 不对为 false

falg=False

nums[i]nums[i + 1] = nums[i + 1] , nums[i]

i += 1

if flag:

#这一趟走完,flag 依然是 Ture,说明这一趟没有进行过数据交换

break//停止循环

j += 1  //进行下一趟

print(nums)

print(‘比较了%d’ %count)

输出结果

[12345678]

比较了27

总结

设立一个 flag=Ture,当发现本趟未执行数据交换时,就不会执行 if nums [i] > nums [i+1]flag 不变为 false,执行 if flag:

后的 break 退出循环。

2.  一键替换变量名

Tip:一键替换代码中的 flag 变量名,直接双击 flag,右键找到 Refactor Rename 重命名将其改为要更换的变量名 a 即可。

1.png

4.优化效果

在列表数据为[6,5,3,1,8,7,2,4]这样乱序时优化并不明显。但是当列表的数据几乎排序好时,如[1,2,3,4,5,6,7,9,8],在未优化时仍需要64次,但加上优化每一趟比较次数之后仅需要36,而优化总比较趟数之后就变为15次。


相关文章
|
搜索推荐 算法 索引
冒泡排序算法的实现和优化~
冒泡排序算法的实现和优化~
|
搜索推荐 算法
|
6月前
|
搜索推荐 算法 JavaScript
探索冒泡排序:原理、实现与优化
探索冒泡排序:原理、实现与优化
|
6月前
|
搜索推荐 算法 数据处理
从程序设计的角度探索排序算法:冒泡排序的实现与优化
从程序设计的角度探索排序算法:冒泡排序的实现与优化
36 0
|
6月前
|
搜索推荐 算法
常见排序算法以及冒泡排序的基础使用方法
常见排序算法以及冒泡排序的基础使用方法
40 0
|
搜索推荐 算法
深入探究排序算法:快速排序的实现与优化
排序算法是计算机科学中的基础知识,它们在各种应用和场景中都扮演着重要角色。本文将深入探讨一种经典的排序算法——快速排序,并介绍其实现原理及优化技巧。
82 1
|
搜索推荐 算法 C++
选择排序算法的实现和优化
选择排序算法的实现和优化
|
算法 搜索推荐 C语言
用或不用大O来优化代码(选择排序)
用或不用大O来优化代码(选择排序)
84 0
|
算法 搜索推荐
【21天算法学习】冒泡排序
【21天算法学习】冒泡排序
70 0
|
搜索推荐 算法
冒泡排序以及优化
冒泡排序以及优化
152 0
冒泡排序以及优化