python实现冒泡排序
冒泡排序(从小到大排序):
冒泡排序的思路为拿第一个数与后面的数一一对比,如果前一个数比后一个数大那么将位置互换,这一经过一次可以使得最大的元素置于最后
如图排序数为:54 26 93 17 77 31 44 55 20
如图所示,经过一次排序以后93跑到了最后一个位置,经过八次这样的循环便可得到排序后的数字
def BubleSort(alist):
n=len(alsit)
#第一次比较
for i in range(n-1):#这里的循环只能是0——n-2,
#我们知道n-1是最后一个数字,如果是n的话,那么alist[i+1]就是alist[n]是一个未知数了。
if alist[i]>alist[i+1]:
#如果前一个元素比后一个元素大,互换元素
alist[i],alist[i+1]=alist[i+1],alist[i]
但是我们是需要全部进行排序的,所以代码不可能这样子写,是需要两个for循环语句来实现的。
我们就以排序数为:54 26 93 17 77 31 44 55 20 为例子。
首先我们可以看出需要对其进行8次一次排序操作。
(1)26 54 17 77 31 44 55 20 93
(2)26 17 54 31 44 50 20 77 93
(3)17 26 31 44 50 20 54 73 93
(4)17 26 31 44 20 50 54 73 93
(5)17 26 31 20 44 50 54 73 93
(6)17 26 20 31 44 50 54 73 93
(7)17 20 26 31 44 50 54 73 93
(8)17 20 26 31 44 50 54 73 93
那么我们设置第一个循环的话j就是从range(0,n-1)中去循环,那么第二个循环i是与第一个循环有关系的。
例如当 j=0, i就要从0——n-2
当j=1, i就要从0——n-3
当j=2, i就要从0——n-4
以此类推 就可以得到i是从range(0,n-1-j)中去循环。这里可以通过画图方式去理解。再每次j循环一次后,需要排序的数字就会少一个,(因为在每次的j循环最后一个元素都是最大的,无需在对后面的数字对比。)
def BubleSort(alist):
"""冒泡排序""""
n=len(alist)#记录表长
for j in range(n-1):
#执行的次数
for i in range(0,n-1-j):
#每一次循环一个一个比较前后元素的大小
if alist[i]>alist[i+1]:
alist[i],alist[i+1]=alist[i+1],alist[i]#元素互换
if __name__=="__main__":
a=[54,26,93,17,77,31,44,55,20]
print("排序之前的数为:")
print(a)
print("排序之后的数为:")
BubleSort(a)
print(a)
时间复杂度:
for j in range(n-1):
for i in range(0,n-1-j):
if alist[i]>alist[i+1]:
这里面有两个循环,第一个循环执行次数为n-1,第二个循环是从 n-1,n-2,n-3 .。。。。。这一循环,所以两个循环的可以都看出n,所以最坏的复杂度为O(n*n),最优复杂度为O(n)。
代码优化:
对于本来就排序好的列表来说,我们没必要进行上面的代码,这样比较的话时间复杂度为O(n*n)。
如[1,2,3,4,5,6] 如果按照上面的代码,我们需要执行两个for循环才可以。其实呢!没必须,因为这个本来就是排序好的列表了,那么我们优化代码如下
def BubleSort(alist):
"""冒泡排序""""
n=len(alist)#记录表长
for j in range(n-1):
#执行的次数
count=0 #初始化计数变量
for i in range(0,n-1-j):
#每一次循环一个一个比较前后元素的大小
if alist[i]>alist[i+1]:
alist[i],alist[i+1]=alist[i+1],alist[i]#元素互换
count+=1# 如果进行了交换就对count进行+1操作
if 0==count:#如果count等于0就说明没有进行上面if条件里面的内容,也就是说没有交换
return
if __name__=="__main__":
a=[54,26,93,17,77,31,44,55,20]
print("排序之前的数为:")
print(a)
print("排序之后的数为:")
BubleSort(a)
print(a)