前言
之前写过一篇关于Python算法分析的文章--《利用 Python 浅尝算法分析》,想要学好计算机,数据结构和算法几乎是无法回避的课题,因为我们学习编程第一节课老师都会跟你说:程序 = 数据结构 + 算法.所以说这必学的编程基础知识.
在数据结构和算法这门课程中排序与查找算法是我们常用的算法,而且这两者也是我们工作中常用的算法.就比如排序就有很多经典的算法.;排序是让数据能够以更有意义的形式表现出来.而查找的意义是在一个数据集中找到元素的位置.接下来本文就来学习下经典的冒泡排序
什么是冒泡排序
冒泡排序是一种较为简单且经典的排序算法,基本所有学习算法的人都认识它,它会重复地访问要排序的数列.每次都比较两个元素.如果发现顺序不对就将他们交换过来.由于这个排序算法会很形象的将元素慢慢的浮起,就是不断的交换元素,就像水中的气泡一样,气泡一层一层向上走,越靠近水面的气泡越大,因此称为冒泡排序
如何实现冒泡排序
接着咱们使用实例来详细说明冒泡排序.首先我们先构建一个乱序的数列.这里就随机取数并创建一个整数列表.然后使用冒泡排序将这个列表进行升序排序
简单来说,冒泡排序就是从需要排序的n个数字元素的第一个数字开始,对数字进行两两比较,将两者中较大的数字向后移动。经过第一趟排序,共比较n-1次,整个数字元素中最大的数字将在整串数字末尾;经过第二趟排序,比较n-2次,第二大数字就会排在倒数第二位
列表数据为:[24,6,18,11,9,8]
,这是一个乱序的列表,接下来使用冒泡排算法对其进行排序.让他变成一个有序数列
为了更直观地展示冒泡排序的步骤,先画出图示再根据图示进行代码实现
两两互相交换的过程如下:
图中每一次选定的数都会重头开始和第一个元素到相邻的前一个元素比较,顺序不对就交换,直到所有的元素都比较完,排序完成
实践才是检验真理的标准,接着按照图示书写代码:
lists= [24,6,18,11,9,8] foriinrange(len(lists)): forjinrange(i+1): iflists[i] <lists[j]: lists[i],lists[j] =lists[j],lists[i] #交换print(lists)
结果:
上面的程序使用了两层for循环嵌套.外层控制元素的选取,内层用于比较并交换位置,直到整个排序完成
算法优化
现在算法每个元素需要循环比较的次数为n次,那如果部分已经排好序的根本就不需要比较了,不然纯属浪费时间,那应该怎么优化呢?
我们可以定义一个标记变量flag来记录值初始值为True,如果此次循化(这一趟)下来发生了交换,则为False;如果本趟没有发生交换,否则说明排序已完成,为False,则可以结束循环
lists2= [24,6,18,11,9,8] foriinrange(len(lists2)-1): flag=True#用order来记录这一趟是否发生了数字交换forjinrange(len(lists2)-i-1): iflists2[j] >lists2[j+1]: lists2[j],lists2[j+1] =lists2[j+1],lists2[j] flag=False#若发生交换,改变flag变量的值ifflag==True: #若flag值没有发生变化,则证明本趟没有数字交换,此时数列已经有序,break退出排序breakprint(lists2)
结果:
总结
算法稳定性:两两比较若值相等没有发生位置交换
稳定
算法时间复杂度:
最好最差的情况,时间复杂度均为 O(n^2)
算法空间复杂度:
若最优的空间复杂度就是起始元素顺序已经排好了,则空间复杂度为:0
若最差的空间复杂度就是起始元素都是逆序排序的,则空间复杂度为:O(n)
平均的空间复杂度为:O(1)