Python排序算法

冒泡排序:
  1. 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
def bubble_sort(array):
    for j in range(len(array) - 1, 0, -1):
        for i in range(j):
            if array[i] > array[i + 1]:
                array[i], array[i + 1] = array[i + 1], array[i]
    return array

时间复杂度: 最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
最坏时间复杂度:O(n**2)
稳定性:稳定

选择排序:
  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 以此类推,直到所有元素均排序完毕。
def select_sort(array):
    length = len(array)
    for i in range(length):
        min_index = i
        for j in range(i + 1, length):
            if array[j] < array[min_index]:
                min_index = j
        if min_index != i:
            array[i], array[min_index] = array[min_index], array[i]
    return array

时间复杂度:最优时间复杂度:O(n2)
最坏时间复杂度: O(n
2)
稳定性:不稳定(考虑升序每次选择最大的情况)

插入排序
  1. 构建有序序列
  2. 对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
  3. 插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
def insert_sort(array):
    length = len(array)
    for i in range(1, length):
        for j in range(i, 0, -1):
            if array[j] < array[j-1]:
                array[j], array[j-1] = array[j-1], array[j]
    return array

时间复杂度:
最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
最坏时间复杂度:O(n**2)
稳定性:稳定

快速排序:
  1. 从数列中挑出一个元素,称为"基准"(pivot)
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  4. 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去
def quick_sort(array, start, end):
    if start >= end:
        return array

    pivot = array[start]
    low = start
    high = end

    while low < high:
        while low < high and array[high] >= pivot:
            high -= 1
        array[low] = array[high]

        while low < high and array[low] <= pivot:
            low += 1
        array[high] = array[low]

    array[low] = pivot

    quick_sort(array, start, low - 1)
    quick_sort(array, low + 1, end)

    return array

时间复杂度:
最优时间复杂度:O(nlogn)
最坏时间复杂度:O(n2)
稳定性:不稳定

希尔排序:
  1. 对要排序的列表根据一定间隔(初始间隔一般设为列表长度的一半)进行分组
  2. 对各列表之间相同位置(下标)的元素进行插入排序
  3. 间隔减半,再次分组并对各列表之间相同位置(下标)的元素进行插入排序
  4. 如此循环,最终间隔为1,即为正常的插入排序
def shell_sort(array):
    length = len(array)
    gap = length // 2
    while gap > 0:
        # 按步长插入排序
        for i in range(gap, length):

            while i >= gap and array[i - gap] > array[i]:
                array[i - gap], array[i] = array[i], array[i - gap]
                i -= gap

        gap = gap // 2

    return array

时间复杂度
最优时间复杂度:根据步长序列的不同而不同
最坏时间复杂度:O(n2)
稳定性:不稳定

归并排序:
  • 假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列,再两两归并,最终得到一个长度为n的有序序列为止,这称为2路归并排序。
def merge_sort(array):
    if len(array) <= 1:
        return array
    num = len(array) // 2
    left = merge_sort(array[:num])
    right = merge_sort(array[num:])

    return merge(left, right)


def merge(left, right):
    print(left, right)
    l, r = 0, 0  # 两个列表的起始位置指针
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result

时间复杂度:
最优时间复杂度:O(nlogn)
最坏时间复杂度:O(nlogn)
稳定性:稳定

基数排序:
  1. 按照个位数进行排序。
  2. 按照十位数进行排序。
  3. 按照百位数进行排序。排序后,数列就变成了一个有序序列。
def radix_sort(array):
    mostBit = len(str(max(array)))
    for i in range(mostBit):
        bucket = [[] for _ in range(10)]
        for j in array:
            bucket[j//(10**i) % 10].append(j)
        array = [j for i in bucket for j in i]

    return array

时间复杂度:O(nlog®m),其中r为所采取的基数,而m为堆数
空间复杂度:O(n) 稳定性:稳定

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值