python实现冒泡排序 -- 详细分析思路


1. 冒泡排序的思想

重复遍历要排序的数列,每次比较两个位置的元素,如果不符合排序规则,则交换两个位置的元素,一直遍历到没有需要交换的元素后,排序才算完成。


2. 冒泡排序实现步骤

冒泡排序可以可以在顺序表或链表中实现,下面使用顺序表为例实现冒泡排序,排序规则为把一组数从小到大进行排列。


2-1 单个元素实现排序

假定target_list为[10,9,7,3,5,6,2,1,4],要求使用冒泡排序将此列表的元素从小到大进行排列。
我们先从第一轮遍历开始研究,从索引为0的元素开始两两比较,如下图所示:索引为0-8,绿色箭头为游标。

冒泡排序.png

  • 令数组的长度为n,则target_list的长度为9,索引为0-8【n = len(target_list) 】
  • 设游标所在的索引位置为i【一开始在0索引位置】,开始遍历数组后,游标每次往后移动一个位置,每移动一次,对比 i 和 i + 1 位置元素的大小,如果位置i的元素比i + 1 位置的元素大,则交换两个元素的位置,反之不交换。
    【上图中的10,由于每次比较都比后一个元素大,因此会不断的往后走,最终被排列在数组的末尾】
  • 那么遍历的条件怎么写呢?是否是(0,n-1)【索引为0,n-1】?答案是否定的,因为
    我们比较的是 i 和 i+1 位置的元素,因此游标只需要走到 n-2 的位置即可。而range函数范围左闭右开,因此遍历的条件为range(0,n-1)
#
'''单次遍历冒泡排序分析'''
n = len(target_list)
for i in range(n-1):
    if target_list[i] > target_list[i+1]:
       # 如果位置i的元素比i+1位置的元素大,则交换两个元素的位置
       target_list[i],target_list[i+1] = target_list[i+1],target_list[i]
# 

2-2 思路扩展到所有元素

知道了单个元素的冒泡排序原理后,我们就可以将其运用到所有元素上。那么我们是否需要所有元素都执行一次冒泡排序呢?可以,但没必要。因为当我们确定了n-1个元素的位置后,剩下的一个元素的位置就已经确定了,因此我们只需要遍历n-1次即可。

  • 设 j 为遍历的次数,则 j 的范围为(0,n-1)

  • 单个元素实现排序时,我们让游标从0索引位置一直走到n-2索引的位置,那么在对数组进行遍历排序每个元素时,是否在遍历每个元素时,游标都需要从0索引位置走到n-2索引的位置?答案是否定的,因为每遍历一次,就有一个元素的位置确定了,下一次遍历的元素就不再需要和这个元素进行位置对比,因此游标需要走的长度是不断减少的,那么减少多少呢?

  • 由上表可得,遍历了n-1次后,我们便能确定n-1个元素的位置,确定了n-1个元素的位置后,剩下1个元素的位置也可以确定,即所有元素的位置都能确定。由此,每次i需要走的长度为n-1-j。
    【这里可能不那么好理解,可以多画几个图,看每次游标需要走的长度是多少,就能理解了】

def bubble_sort(target_list):
    n = len(target_list)
    for j in range(n-1):
        for i in range(n-j-1):
            if target_list[i] > target_list[i+1]:
                target_list[i],target_list[i+1] = target_list[i+1],target_list[i]

    return target_list


2-3 代码优化

上面已经完成了冒泡排序的代码,但是如果给定的 target_list 本身就是一个从小到大排序的顺序列表呢?那跟无序列表一样遍历n-1次就没有任何意义了,因此为了提高最优情况下的代码效率,我们加入一个计数器count,遍历过程中,target_list[i]和target_list[i+1]每交换一次,则计数+1,如果没有发生交换,则说明这是个顺序列表,此时,就可以跳过遍历过程,这样就可以提高最优情况下的代码效率了。

def bubble_sort(target_list):
    n = len(target_list)
    for j in range(n-1):
        # 加入计数器
        count = 0
        for i in range(n-j-1):
            if target_list[i] > target_list[i+1]:
                target_list[i],target_list[i+1] = target_list[i+1],target_list[i]
                count += 1
        # 如果count ==0,则结束循环
        if count == 0:
            return
    return target_list

以上是用顺序表实现冒泡排序的思路和代码,小伙伴们也可以使用链表来实现冒泡排序,思路都差不多。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容