递归、分治·、快排及归并排序

本文详细介绍了归并排序算法,通过递归实现分治策略,将大问题分解为较小的子问题,利用二分法快速排序最小序列,然后通过稳定合并过程达到O(nlogn)的时间复杂度。对比了快速排序的随机化特性,展示了归并排序的稳定性和效率特点。
摘要由CSDN通过智能技术生成

递归

递归

分治

merge sort

对原list不断二分,最小序列为两个元素或一个元素的序列(二分时间复杂度O(logn),对最小序列排序(两元素比较大小)
然后子序列两两归并(合并两个升序数组,O(n)),总时间复杂度为O(nlogn),空间复杂度:需要新列表储存所有元素,O(n)
由于两个子序列合并时,对于值相等的元素,总是先复制左边再复制右边,不会改变原序列元素的位置,因此归并排序是稳定排序算法

"merge sort"
class MergeSort:
	#########合并两个升序lsit#########
    def merge(self,l1,l2):
        l=[]
        while l1 and l2:
            a,b=l1[0],l2[0]
            if a<=b:
                l.append(a)
                del l1[0]
            else:
                l.append(b)
                del l2[0]
        if l1==[]:return l+l2
        if l2==[]:return l+l1
    def mergesort(self,l):
    	####停止条件,子序列只含有1个或2个元素####
        if len(l)==1:return l
        if len(l)==2:
        	#####对两个元素排序####
            if l[0]<=l[1]:return l
            else:
                l[0],l[1]=l[1],l[0]
            return l
        #####二分######
        left,right=l[:len(l)//2],l[len(l)//2:]
        #####归并######
        return self.merge(self.mergesort(left),self.mergesort(right))

quick sort

思想:选择一个基准值,比基准值小的在左侧,比基准值大的在右边
对左右两侧的子序列分别选择新的基准值再次划分,至子序列只剩下一个或两个元素
复杂度:
最差情况:快排性能取决于基准值的选择,如果输入是一个有序数列,每次基准值取序列的第一个元素,那么每次左侧的子序列为空,需要取n次基准值才能得到最小序列。每次取子序列,需要比较所有元素与基准值的大小关系,时间复杂度O(n),总时间复杂度O(n^2)
最好情况:对于一个有序序列,每次基准值都取中间的元素,即每次对原序列不断二分,需要取logn次,因此最好时间复杂度为O(nlogn)
平均情况:每次随机选择一个元素作为基准值,其性能将逼近O(nlogn)
空间复杂度O(logn)
快排会改变相同值原来的相对位置,不稳定

"quick sort"
import random
def QuickSort(L):
	###终止条件:子序列只有1或0个元素####
    if len(L)<2:return L
    #######随机取一个元素为基准值########
    p=random.randint(0,len(L)-2)
    pivot=L[p]

	#####将小于或等于基准值的元素放到左序列,大于基准值的放到右序列#######
    left=[i for i in L[:p] if i<=pivot]+[i for i in L[p+1:] if i<=pivot]#注意排除掉作为基准值的元素
    right=[i for i in L[:p] if i>pivot]+[i for i in L[p+1:] if i>pivot]  
    return QuickSort(left)+[pivot]+QuickSort(right)

快排与归并排序性能比较

快排随机取基准值,其平均性能接近最优性能,时间复杂度为O(nlogn)
虽然平均时间复杂度都为O(nlogn),但是快排完成一次操作的单位时间远快于归并排序(归并需要合并升序序列),因此平均情况快排的速度要快很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值