Algorithms -sort

1.选择排序

从数组中选择最小元素,将它与数组的第一个元素交换位置。再从数组剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。

选择排序需要 ~N2/2 次比较和 ~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。

def selection_sort(collection
):
    n = len(collection)
    for i in range(n-1):
        least = i
        for j in range(i+1, n):
            if collection[j] < collection[i]:
                least = j
        collection[i], collection[least] = collection[least],collection[i]
                
    return collection

2.冒泡排序

从左到右不断交换相邻逆序的元素,在一轮的循环之后,可以让未排序的最大元素上浮到右侧。

在一轮循环中,如果没有发生交换,那么说明数组已经是有序的,此时可以直接退出。

def bubble_sort(collection
):
    n = len(collection)
    for i in range(n-1):
        swapped = False
        for j in range(n-i-1):
            if collection[j] > collection[j+1]:
                swapped = True
                collection[j], collection[j+1] = collection[j+1],collection[j]
        if not swapped:
            break
    return collection

3.插入排序

每次都将当前元素插入到左侧已经排序的数组中,使得插入之后左侧数组依然有序。

对于数组 {3, 5, 2, 4, 1},它具有以下逆序:(3, 2), (3, 1), (5, 2), (5, 4), (5, 1), (2, 1), (4, 1),插入排序每次只能交换相邻元素,令逆序数量减少 1,因此插入排序需要交换的次数为逆序数量。

插入排序的时间复杂度取决于数组的初始顺序,如果数组已经部分有序了,那么逆序较少,需要的交换次数也就较少,时间复杂度较低。

平均情况下插入排序需要 ~N2/4 比较以及 ~N2/4 次交换; 最坏的情况下需要 ~N2/2 比较以及 ~N2/2 次交换,最坏的情况是数组是倒序的; 最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。

def insertion_sort(collection
):
    n = len(collection)
    for i in range(1, n):
        j = i-1
        v = collection[i]
        while j>=0 and collection[j]>v:
            collection[j+1] = collection[j]
            j = j-1
        collection[j+1] = v
    return collection

4.归并排序

对一个需要排序的数组,先把它一分为二,对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序的数组

def merge_sort(collection
):
    def merge(left, right):
        result = []
        while left and right:
            result.append((left if left[0] <= right[0] else right).pop(0))

        return result+left+right

    if len(collection)>1:
        mid = len(collection)//2
        left = collection[:mid]
        right = collection[mid:]
        return merge(merge_sort(left), merge_sort(right))
    return collection
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值