冒泡排序

175 阅读2分钟
#!/usr/bin/env python3
# -*- encoding:utf-8 -*-
"""
@author: jjcoder
@file: 冒泡排序.py
@time: 9/12/197:38 AM
"""
"""
最优时间复杂度:O(n) 表示遍历一次发现没有任何可以交换的元素,排序结束
最坏时间复杂度:O(n^2)
稳定性: 稳定

冒泡排序的运作过程(这里按照升序的方式):
1.从头开始比较相邻两个元素,如果第一个比第二个大,交换他们
2.对每一对相邻元素做相同的工作, 这步做完之后,会发现最后一个元素是最大的.
3.针对所有元素重复以上的步骤,除了最后一个
4.继续重复以上步骤,知道不在出现需要交换的元素.
"""


# 这里使用顺序表来做, 也可以使用链表,但是复杂在交换元素的过程
def bubble_sort(alist):
    """冒泡排序"""
    n = len(alist)  # 每一次遍历并不需要游标走到最后一位
    for j in range(n - 1):
        # 这里有一种优化方式: 如果列表已经是有序的了(或者在中途交换的某次已经是有序了,那么也会退出循环, 
        # 避免重复的遍历), 那么按照这种方式他的时间复杂度还是O(n^2),这时就不满足际情况, 应该是O(n), 所以需要优化.
        count = 0  # 这里写一个count用来获取是否有交换的情况.
        for i in range(n - 1 - j):  # 这里有一个细节点需要注意, 在操作元素的时候,我们通过下标的方式,而不是
            if alist[i] > alist[i + 1]:  # for i in alist:这种方式来,这是在操作元素,不方便我们使用.
                alist[i], alist[i + 1] = alist[i + 1], alist[i]
                count += 1
        if 0 == count:
            break


# 外层循环控制要遍历多少次(n次range(n - 1)), 内层循环控制每一次遍历(range(n - 1 -j))
"""
i 0 ~ n-1   range(0, n-1)   j = 0   |  range(0, n - 1)
i 0 ~ n-2   range(0 ~ n-2)  j = 1   |  range(0, n - 1 - 1)
i 0 ~ n-3   range(0 ~ n-3)  j = 2   |  range(0, n - 1 - 2)
i 0 ~ n-4   range(0 ~ n-4)  j = 3   |  range(0, n - 1 - 3)
i 0 ~ n-5   range(0 ~ n-5)  j = 4   |  range(0, n - 2 - 4)

最后的结果: range(0, n - 1 - j) (总的来说, 已经排列过的匀速不需要在排了)
"""


def bubble_sort01(alist):  # 这是另外一种实现形式
    n = len(alist)
    for j in range(n - 1, 0, -1):
        # [n - 1, n - 2, n - 3, n - 4, ..., 1]
        count = 0
        for i in range(j):
            if alist[i] > alist[i + 1]:
                alist[i], alist[i + 1] = alist[i + 1], alist[i]
                count += 1
        if 0 == count:
            return


if __name__ == "__main__":
    li = [11, 44, 22, 77, 99, 101, 22]
    print(li)
    bubble_sort(li)
    print(li)