Python实现快速排序算法

快速排序也是使用了分治思想的排序方法,但与归并排序不一样的是“分”的时候的依据。归并排序“分”的依据是对半分,不管大小,而快速排序则是选定数组中的一个值,以这个值为依据,将数组分为三个部分:小于这个值的部分,大于等于这个值的部分,这个值。这样就以选定的点将数组分为两部分(小于值的部分,大于等于值的部分),然后再通过迭代对这两个部分分别继续执行这样一个“分”的过程,直至最后只剩下1-2个元素,即无法再“分”时,此时数组也排序完成。
下面以图示的方法展示一下第一次“分”的过程。
首先给出要排序的数组 l = [ 2 , 8 , 7 , 1 , 3 , 5 , 6 , 4 ] l=[2,8,7,1,3,5,6,4] l=[2,8,7,1,3,5,6,4] s t a sta sta e n d end end分别为数组的首尾下标。利用 i i i j j j这两个数进行迭代。令 i = s t a − 1 , j = s t a i=sta-1,j=sta i=sta1,j=sta
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
迭代过程中分成了这样几个部分:
在这里插入图片描述
i i i所在的位置是 &lt; e n d &lt;end <end的最新的一个值,在“分”的最后,将返回 i + 1 i+1 i+1,即用来比较的值的位置,以供下次迭代。
具体的python代码实现如下。

#将数组分为两部分
def partition(l0,sta,end):
    i=sta-1
    for j in range(sta,end):
        if l0[j]<l0[end]:
            i=i+1
            #如果j所在的位置的值小于end,则i往前进一步,并与j的值交换,即将一个新的值加入到<end的区域
            x=l0[i]
            l0[i]=l0[j]
            l0[j]=x
    #一次“分”结束,将用于比较的值放在应该在的地方(两个区域的中间)
    i=i+1
    x=l0[i]
    l0[i]=l0[end]
    l0[end]=x
    return i
    
def quicksort(l0,sta,end):
    #当至少存在两个元素时,才进行接下来的分解
    if sta<end:
        mid=partition(l0,sta,end)
        #分成的sta—mid-1,mid+1—end两个区域接着进行分解、迭代
        quicksort(l0,sta,mid-1)
        quicksort(l0,mid+1,end)
    return l0

快速排序的最坏情况,即每次分解时都极其不平衡,分解为 n − 1 n-1 n1个元素和 0 0 0个元素,这样分解操作的时间复杂度为 Θ ( n ) Θ(n) Θ(n),而对大小为 0 0 0的数组进行迭代会直接返回,时间复杂度可以忽略。这样算法运行时间的递归式为
T ( n ) = T ( n − 1 ) + Θ ( n ) T(n)=T(n-1)+Θ(n) T(n)=T(n1)+Θ(n)
解为 T ( n ) = Θ ( n 2 ) T(n)=Θ(n^2) T(n)=Θ(n2)
而最好的情况则是每次都对半分,这样算出的时间复杂度为 Θ ( n l g n ) Θ(nlgn) Θ(nlgn)
而即使是每次的划分达到 9 : 1 9:1 9:1这样一个很不平衡的状态,最终算出的时间复杂度也是 Θ ( n l g n ) Θ(nlgn) Θ(nlgn),事实上,即使是 99 : 1 99:1 99:1也是这样的时间复杂度。(结论和推导均来自《算法导论》)
所以快速排序法的期望时间复杂度为 Θ ( n l g n ) Θ(nlgn) Θ(nlgn),是一个优秀的排序算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值