zoukankan      html  css  js  c++  java
  • [排序N大件之]冒泡排序

    冒泡排序,这个作为萌新入门排序时,最最最基础(没有之一)的排序方法,但是本蒟蒻果冻居然时隔四年之后全忘了,甚至有点无法理解(????),所以一下全部内容都是本蒟蒻果冻的个人理解。

    给出一个列表:[3, 2, 9, 7, 4, 8, 1],怎么变成有序排列?

    冒泡排序是一种基于[比较]-[交换]的排序

    比较:从第一个数(下标为[0])开始,相邻的两个数一次进行比较,如果前者比后者大,那么交换两个相邻的数,最后一次比较是[n-2]和[n-1]下标的元素

    所以第一趟比较的次数是多少:n-1,其中n是待排序的列表的大小

    那么最后一趟比较的次数是多少:1,就是比较[2]和[1]的元素

    可见冒泡排序一共要比较n-1趟

    所以以上两条的趟数确定了冒泡循环的外层循环:for ps in range(n - 1, 0, -1) ----------注意了!!python的range是一个左闭右开的区间,所以真正的区间为[n-1, 1]

    这里倒着取,完全是为了比较的方便

    外内循环有了,内存循环呢?

    冒泡排序和其他的垃圾排序(选择排序,插入排序:时间复杂度为O(n2))有一点不同,后两者部分有序的排列维持在列表的前段(通常情况,本人使用),然后一直往后扩展;

    而冒泡排序,由于每一个最大的元素都像水中上浮的气泡一样,慢慢的“冒”到列表的末尾,因此,对于冒泡排序来说,部分有序的排列,维持在列表的后部分,所以就要对于部分有序排列部分的之前的元素进行比较排序

    观察没一趟比较的元素,可以看出,对于每一趟比较:

    • 第一趟比较的前者元素下标从0到n-2,而后者元素是前者的+1(n-1),第一趟比较交换结束后,最大值元素已经在[n-1]就位了
    • 第二趟比较的元素前者下标从0到n-3,而后者元素是前者的+1(n-2),第二趟比较交换结束后,第二大元素已经在[n-2]就位了
    • 最后一次比较的元素前者下标为0,后者下标为1,到这里这个列表都排序完成

    所以每一趟比较元素的下标范围,正好是外争循环的趟数-1(ps - 1)--------------这里注意了!!由于python新手友好,range右边取不到,所以我们右括号就只要取到ps(趟数)就可以了!!!

    内层循环:for i in range(ps):

    两重循环有了,剩下的该干嘛干嘛,交换两个元素总该会了吧

    def bubbleSort(nums):
    
        n = len(nums)
    
        for ps in range(n - 1, 0, -1):
            for i in range(ps):
                if nums[i] > nums[i + 1]:
                    nums[i], nums[i + 1] = nums[i + 1], nums[i]
    
        return nums
    
    if __name__ == "__main__":
        numbers = [3, 2, 9, 7, 4, 8, 1]
        print(bubbleSort(numbers))

    但是冒泡排序作为三大垃圾排序之首,它可以进行优化,需要一个flag(exchange),优化的基本思想就是:如果这一趟没有出现元素交换,就说明已经排序好了,就没有继续比较的必要了

    优化代码:

    def bubbleSort(nums):
    
        n = len(nums) - 1
        exchange = True
        while exchange and n > 0:
            exchange = False
            for i in range(n):
                if nums[i] > nums[i + 1]:
                    nums[i], nums[i + 1] = nums[i + 1], nums[i]
                    exchange = True
    
            n = n - 1
    
        return nums
    
    if __name__ == "__main__":
        numbers = [3, 2, 9, 7, 4, 8, 1]
        print(bubbleSort(numbers))

    时间复杂度:O(n2)

    如果是进行优化过后的冒泡排序,那么最好的时间复杂度为O(n),对于一个已经排序好的列表,第一趟遍历列表时,发现没有交换...

    空间复杂度:O(1)

  • 相关阅读:
    数独
    canvas生成图片并保存到本地文件夹主要代码
    2048未完成
    Page
    IDEA新建MAVEN项目时速度缓慢
    Bug 记录(持续更新。。。)
    RecyclerBaseAdapter 和 OnItemClickListener
    AutoLoadRecyclerView
    BaseActionBarActivity
    Volley + OkHttp3 + Gson 组合的简单网络请求封装
  • 原文地址:https://www.cnblogs.com/canaan233/p/13718882.html
Copyright © 2011-2022 走看看