排序算法总结(Python版本)

看了很多排序算法,每种算法都有多个版本,现总结一版自己觉得容易理解的,供以后翻阅。

1.插入排序

直接插入排序

直接插入排序是将一个数插入到已经排序好的序列中。做法是先将第一个数作为已经排序好的,依此将后面的数取出插入到前面已排序好的序列中。

def insert_sort(nums):
    for i in range(len(nums)):
        for j in range(i):
            if nums[j]>nums[i]:
                #nums.insert(j,nums.pop(i))
                nums[j],nums[i]=nums[i],nums[j]
    return nums

关于插入的具体操作,这里既可以用 nums[j],nums[i]=nums[i],nums[j],也可以用 nums.insert(j,nums.pop(i))

时间复杂度为,空间复杂度为。是稳定的排序算法。

希尔排序

先按一定的增量将数据分组,每组进行直接插入排序,随着增量的减少,每组的数越来越多,最后所有数据成为一组。

def shell_sort(nums):
    step=len(nums)//2
    while step>0:
        for i in range(step,len(nums)):
            while i>=step and nums[i-step]>nums[i]:     #每组进行直接插入排序
                nums[i-step],nums[i]=nums[i],nums[i-step]
                i-=step
        step//=2    #增量每次的变化
    return nums
时间复杂度为 ,空间复杂度为 。不是稳定的排序算法。


2.交换排序

冒泡排序

从序列头开始,每次比较两个元素。若他们顺序错误则进行交换,直到遍历完序列为止。

def buble_sort(nums):
    for i in range(len(nums)):
        for j in range(i+1,len(nums)):
            if nums[i]>nums[j]:
                nums[i],nums[j]=nums[j],nums[i]
    return nums
时间复杂度为 ,空间复杂度为 。是稳定的排序算法。
快速排序

通过一趟排序将序列分为两部分,一部分比某个数大,另一部分比某个数小。再按此方法对两部分数据进行排序,知道整个序列有序。

def quick_sort(nums):
    if nums==[]:
        return []
    else:
        partition=nums[0]
        left=quick_sort([l for l in nums[1:] if l<partition])
        right=quick_sort([r for r in nums[1:] if r>=partition])
        return left+[partition]+right

时间复杂度为,空间复杂度为。不是稳定的排序算法。

3.选择排序

简单选择排序

第1趟,在待排序记录r1 ~ r[n]中选出最小的记录,将它与r1交换;第2趟,在待排序记录r2 ~ r[n]中选出最小的记录,将它与r2交换;以此类推,第i趟在待排序记录r[i] ~ r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

def select_sort(nums):
    for i in range(len(nums)):
        x=i
        for j in range(i+1,len(nums)):
            if nums[j]<nums[x]:
                x=j
        nums[x],nums[i]=nums[i],nums[x]
    return nums
时间复杂度为 ,空间复杂度为 。不是稳定的排序算法。
堆排序

它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

def heap_sort(hlist):
    def heap_adjust(parent):
        child=2*parent+1    #左孩子
        while child<len(heap):
            if child+1<len(heap):
                if heap[child]<heap[child+1]:
                    child+=1    #判断左右孩子里的较大值
            if heap[parent]>=heap[child]:
                break
            heap[parent],heap[child]=heap[child],heap[parent]   #最大值作为父节点
            parent,child=child,child*2+1    #调整下一个

    heap,hlist=hlist,[]
    for i in range(len(heap)-1,-1,-1):  #建立大顶堆
        heap_adjust(i)
    while len(heap)>0:
        heap[0],heap[-1]=heap[-1],heap[0]
        hlist.insert(0,heap.pop())    #弹出最大结点并进行调整
        heap_adjust(0)
    return hlist
时间复杂度为 ,空间复杂度为 。不是稳定的排序算法。

4.归并排序

采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

def merge_sort(nums):
    def merge(left,right):
        array=[]
        while left and right:
            if left[0]<right[0]:
                array.append(left.pop(0))
            else:
                array.append(right.pop(0))
        if left:
            array+=left
        elif right:
            array+=right
        return array

    def recursive(nums):
        if len(nums)==1:
            return nums

        mid=len(nums)//2
        left=recursive(nums[:mid])
        right=recursive(nums[mid:])
        return merge(left,right)

    return recursive(nums)
时间复杂度为 ,空间复杂度为 。是稳定的排序算法。


5.基数排序

对于数组中的元素,首先按照最低有效数字进行排序,然后由低位向高位进行。

对于3个元素的数组[977, 87, 960],第一轮排序首先按照个位数字相同的放在一个桶s[7]=[977],s[7]=[977,87],s[0]=[960]执行后list=[960,977,87].第二轮按照十位数,s[6]=[960],s[7]=[977],s[8]=[87],执行后list=[960,977,87].第三轮按照百位,s[9]=[960],s[9]=[960,977],s[0]=87,执行后list=[87,960,977],结束。

def radix_sort(nums):
    s=[[]]
    digit=0
    while len(s[0])!=len(nums):     #所有元素全排到第一个桶后,结束
        s=[[] for i in range(10)]   #定义10个桶
        for i in nums:
            index=i//(10**digit)%10     #从个位开始,依次入桶
            s[index].append(i)
        nums=[]
        for i in range(len(s)):
            nums+=s[i]
        digit+=1
    return nums
时间复杂度为O(d(r+n),空间复杂度为O(rd+n)。是稳定的排序算法。


各排序算法总结


猜你喜欢

转载自blog.csdn.net/baike33/article/details/80913638