冒泡算法实现示意图和python代码

对比二分查找和线性查找的步数差异,发现二分查找的步数为O(log N),比线性查找的O(N)快得多。

大O记法能客观地衡量各种算法的时间复杂度,是比较算法的利器。

大O可以与其他常用的算法比较,如果通过大O 发现自己的算法比其他的要慢,就应该退一步,好好想想怎样优化它,才能使它变成更快的那种大O。

虽然并不总有提升空间,但在确定编码之前多加考虑还是好的。

会用大O来测量算法的性能,对算法做些修改,使得性能提升。

排序算法是计算机科学中被广泛研究的一个课题。历时多年,它发展出了数十种算法,这些算法都着眼于一个问题:如何将一个无序的数字数组整理成升序?

冒泡排序是一种很基本的排序算法,步骤如下。
(1) 指向数组中两个相邻的元素(最开始是数组的头两个元素),比较它们的大小。

 (2) 如果它们的顺序错了(即左边的值大于右边),就互换位置。

 

如果顺序已经是正确的,那这一步就什么都不用做。
(3) 将两个指针右移一格。

 

重复第(1)步和第(2)步,直至指针到达数组末尾。
(4)重复第(1)至(3)步,直至从头到尾都无须再做交换,这时数组就排好序了。
这里被重复的第(1)至(3)步是一个轮回,也就是说,这个算法的主要步骤被“轮回”执行,直到整个数组的顺序正确。

假设要对[4, 2, 7, 1, 3]进行排序。它现在是无序的,我们的目标是产生一个包含相同元素、升序的数组。
开始第1 次轮回。
数组一开始如下图所示。

 第1 步:首先,比较4 和2。如图可见它们的顺序是错的。

 第2 步:交换它们的位置。

 第3 步:比较4 和7。

 它们的顺序正确,所以不用做什么交换。

第4 步:比较7 和1。

 第5 步:顺序错误,于是进行交换。

 第6 步:比较7 和3。

 第7 步:顺序错误,于是进行交换。

 

因为一直把较大的元素换到右边,所以现在最右侧的7 正处于其正确位置上。将那个格子用虚线圈起来。
这也正是此种算法名为冒泡排序的原因:每一次轮回过后,未排序的值中最大的那个都会“冒”到正确的位置上。
因为刚才那次轮回做了不止一次的交换,所以得继续轮回。

第8 步:从比较2 和4 开始。

 

它们已经按顺序排好了,所以直接进行下一步。
第9 步:比较4 和1。

 第10 步:它们的顺序错误,于是交换。

 第11 步:比较4 和3。

 第12 步:顺序错误,进行交换。

 

因为7 已经在上一次轮回里排好了,所以无须比较4 和7。此外,4 移到了正确的位置,本次轮回结束。因为这次轮回也做了不止一次的交换,所以得继续轮回。

下面来第3 次轮回。
第13 步:比较2 和1。

 第14 步:顺序错误,进行交换。

 第15 步:比较2 和3。

 

顺序正确,不用交换。
这时3 也“冒”到其正确位置了。因为这次轮回做了不止一次的交换,所以还要继续。
于是开始第4 次轮回。
第16 步:比较1 和2。

 

顺序正确,不用交换。而且剩下的元素也都排好序了,轮回结束。
因为刚才的轮回没有任何交换,可知整个数组都已排好序。

 用Python 写的冒泡排序:

 unsorted_until_index = len(list) - 1

变量unsorted_until_index 表示“该索引之前的数据都没排过序”。一开始整个数组都是没排过序的,所以此变量赋值为数组的最后一个索引。

sorted = False
另外还有一个sorted 变量,被用来记录数组是否已完全排好序。当然一开始它应该是False。

while not sorted:
      sorted = True
接着是一个while 循环,除非数组排好了序,不然它不会停下来。然后,我们先将sorted初步设置为True。当发生任何交换时,我们会将其改为False。如果在一次轮回里没有做过交换,那么sorted 就确定为True,我们知道数组已排好序了。

for i in range(unsorted_until_index):
     if list[i] > list[i+1]:
         sorted = False
         list[i], list[i+1] = list[i+1], list[i]

在while 循环里,还有一个for 循环会迭代未排序元素的索引值。此循环中,我们会比较相邻的元素,如果有顺序错误,就会进行交换,并将sorted 改为False。
unsorted_until_index = unsorted_until_index - 1
到了这一行,就意味着一次轮回结束了,同时该次轮回中冒泡到右侧的值处于正确位置。因为unsorted_until_index 所指的位置已放上了正确的元素,所以减1,以便下一次轮回能略过该位置。
一次while 循环就是一次轮回,循环会持续直至sorted 确定为True。

 

猜你喜欢

转载自www.cnblogs.com/hlaotong/p/12634863.html