常见排序解析

​本文将着重介绍直接插入排序,直接选择排序,冒泡排序,归并排序与快排排序,以下实现皆为升序。

直接插入排序

​特点:稳定,时间复杂度:O(n^2)。

def insertion_sort(a):
    for i in range(1, len(a)):
        while a[i] < a[i-1]:
            a[i], a[i - 1] = a[i - 1], a[i]
            i -= 1
    return a

​排序过程:第一个数一定有序,从第二个值开始,将第二个值放入一个temp中,与第一个进行比较,大于放到第一个后面,不大于则将第一位向后移,将第二个数插入到第一位,此时前两个数已经排列好,第三位重复上述过程,在前部已排好的序列中找到位置并插入,原来插入位置极之后的值向后移。继续执行上述过程,直至排序完毕。

上述程序经过优化,将需要进行排序的数直接与前一位值比较,小于则换位置,然后继续向前比较,换位,直到本轮排序完毕,将向后移与插入的过程转换为比较换位。

直接选择排序

特点:不稳定,时间复杂度:O(n^2)。

def selection_sort(a):
    for i in range(len(a) - 1):
        m = i
        for j in range(i + 1, len(a)):
            if a[m] > a[i]:
                a[m], a[i] = a[i], a[m]
    return a

​排序过程:从第一位开始,与之后位的值进行比较,直到找出最小值,放到第一位,然后从第二位开始比较,直到找出第二小的数放到第二位,重复上述过程,直到排序完成。

冒泡排序

​ 特点:稳定,平均时间复杂度:O(n^2)。

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

排序过程:从第一个数开始,如果第一个数大于第二个,两者换位,继续向后比较,如果不大于则不换位,用第二位向后一位比较,重复上述比较过程。

​上述程序经过优化,已排好顺序的部分将不参与比较。

归并排序

​特点:稳定,时间复杂度O(nlog2n)

def merge_sort(a):
    if len(a) > 1:
        mid = len(a) // 2
        left = merge(a[:mid])
        right = merge(a[mid:])
        i = 0
        j = 0
        k = 0
        l = len(left)
        r = len(right)
        while i < l and j < r:
            if left[i] < right[j]:
                a[k] = left[i]
                i += 1
                k += 1
            else:
                a[k] = right[i]
                j += 1
                k += 1
    return a

​排序过程:采取分治法,将每组都排好序,

快排

​特点:不稳定,时间复杂度:O(nlog2n)

def quick_sort(a):
    if len(a) <= 1:
        return a
    p = a[0]
    g = [e for e in a[1:] if e > p]
    lq = [e for e in a[1:] if e <= p]
    return quick(lq) + [p] + quick(g)

排序过程:选择一个基值(一般为第一个数),将其放在中间位置,定义两个游标,从左边寻找比基值大的数,从右边找比基值小的数,左右两个游标的值交换,执行此操作直至两个指针相遇。一轮结束后,对基数左右两边的数组继续执行上述操作,直到排序完毕。

​快排的每一轮的操作本质上来说就是将大的数放到基值右边,小的数放到基值左边,上述的代码就是通过递归来实现上述思想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值