暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

排序系列之冒泡排序(四)

coolpython 2017-05-18
249

前情回顾

在本系列的第二篇教程里,基本实现了冒泡排序,但是存在多余的比较过程,其原因在于,没一轮比较后,都会有一个数值被移动到它本应该在的位置上,下一轮比较后,这个数值就不需要再参与比较了

本系列的第三篇,解决了这个多余的比较问题,但是,程序仍然存在问题,我们现在已经明白,经过第一轮比较后,序列中最大的那个元素被移动到序列的最后一位,此时,如果前四个元素也是有序的,那么,还需要进行第二轮比较么?之后的第三轮,第四轮有必要进行么?

判断序列当前是否有序

假设有这样一个序列

lst = [5,1,2,3,4]

经过一轮排序后,序列元素的顺序变为 1,2,3,4,5 。它已经是一个有序的序列了,还有必要进行第二轮比较么?有必要!!!

因为经过第一轮比较后,程序还无法判断序列是不是有序,刚才我问你这个问题时,你是通过眼睛观察发现已经有序了,对于程序来说,它也需要观察,而且,只有在一轮排序的过程中才能进行观察。

标识位

如何观察呢?接下来要介绍的是编写程序时经常用到的一种技术手段,设置标识位,我们在每一轮比较开始前,设置一个标识位,创建一个名为flag的变量,赋值为True,它表示当前的序列是有序的,注意,这只是一个假设,我们先假设它有序,而实际的比较过程中,如果出现了lst[j] > lst[j+1] 的情况,我们的假设就不成立了,这时,将flag赋值为False,明确表示,当前的序列是无序的。

这么做有什么用呢?还是以用刚才的例子,在进行第一轮比较时,flag = True,比较过程中,必然发生lst[j] > lst[j+1] ,因为此时序列是无序的,所以一轮比较过后,flag = False

接下来,进行第二轮比较,再次创建flag,flag =True,假设序列有序,在比较过程中,不会发生lst[j] > lst[j+1] ,因为序列已经是有序的了,经过第二轮比较后,flag = True ,你注意,此时flag = True,程序已经明确的表示序列是有序的,我们只需要一个break就可以跳出循环了,之后的比较都不需要了

示例代码

#coding=utf-8


lst = [5,1,2,3,4]

for i in range(len(lst)-1):
   flag = True
   for j in range(len(lst)-1 - i):
       if lst[j] > lst[j+1]:
           flag = False
           lst[j],lst[j+1] = lst[j+1],lst[j]

   print u"第{index}轮比较".format(index=1)
   if flag:
       break

print lst

是否跳出循环,取决于当前的序列是否有序,我们先假设它有序,然后找它无序的证据,这个证据就是lst[j] > lst[j+1],如果没有这种情况,就说明它是有序的,大胆放心的执行break就好了

我们用4篇教程,介绍了冒泡排序,由浅入深,层层递进,希望你能踏踏实实的从第一篇教程跟着编写代码,感受逻辑变化的过程,理解每一个操作的意义,不积跬步无以至千里,相信我,好的基础是你进步的最大动力

文章转载自coolpython,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论