快速排序法原理及python实现代码

版权声明:原创不易,如若转载,请注明出处! https://blog.csdn.net/MG1723054/article/details/85523995

快速排序算法按照字面意思就是时间复杂度"很快'的排序算法,实际上,在所有排序中,快速排序是最快的排序算法。一般的算法复杂度为O(n^2),但是快速排序法的时间复杂度为O(nlogn),所以说快速排序法在排序算法中最快,而且快速排序法不需要额外的内存。

快速排序的原理:

引用图解算法中的图解,我们通过一个具体实例即对一个无序列表[6,1,2,7,9,3,4,5,10,8]中的数进行快速排序.

① 选取一个基数base,习惯上选取左边第一个数。然后分别设置左右两指针,左右指针分别从0,len(data)-1开始向中间靠拢。

首先右指针先移动,寻找比基数base小的数,左指针原地待命,直到右指针找到小于基数base的数。

② 右指针一直向右移动,直到到达元素5 比基数base小,于是右指针暂停,左指针向右移动,直到找到左指针中的元素值比base大,这时元素7比base小,这时交换左右指针i,j中元素中值

③ 交换之后,左指针依旧在右指针左边,也就是i<j, 重复上面步骤① ② 此时i,j分别处在元素5,7的位置。交换。

④ 重复上面的步骤① ②,发现此时左指针i 向右移动到元素3的位置时 i==j 此时左右指针停止移动,我们发现该位置的元素值比base小,交换两个的值。

④ 以 元素3 的位置将列表分成两个部分,分别为[6,1,2,5,4]和[9,7,10,8] 对该两个部分进行上面的步骤(重复步骤可视为递归过程

最后给出本例快速排序过程图以及快速排序的动图

实现代码:

##递归实现快速排序

###注意 首先要右指针条件满足才能移动左指针,也就是说右指针先行
def quickly_sorted(start,end,data):
    if start>=end:
        return data
    else :
        base=data[start]
        i=start
        j=end-1
        while i<j:
            if data[j]<base :##首先右指针移动
                if data[i]>base:###左指针移动
                    data[i],data[j]=data[j],data[i]##满足条件交换
                else :
                    i+=1###若左指针不满足 移动左指针 
            else :
                j-=1###右指针不满足 移动右指针 
        if base>data[i]:
            data[start],data[i]=data[i],data[st
art]

        quickly_sorted(start,i,data)###重复上面的步骤
        quickly_sorted(i+1,end,data)
        return data
data=[6,1,2,7,9,3,4,5,10,8]
start=0
end=len(data)
quickly_sorted(start,end,data)

后面的话:

如果利用该方式递归会出现错误的结果,为什么?因为如果我们要利用data[0:i]相当于创建了一个新的列表,所以在递归返回的时候原列表的内容并不会改变,这也就是在python中的赋值,浅拷贝和深拷贝的区别,这点一定要注意,在后面我会继续写一些关于递归的应用(主要在二叉树中的递归),这里面也会涉及到列表深浅拷贝的区别。

def quickly_sorted(data):
    if len(data)==0 or len(data)==1:
        return data
    elif len(data)==2 and data[0]>data[1]:
        data[0],data[1]=data[1],data[0]
    else :
        start=0
        end=len(data)
        base=data[start]
        i=start
        j=end-1
        while i<j:
            if data[j]<base :
                if i>base:
                    data[i],data[j]=data[j],data[i]
                else :
                    i+=1
            else :
                j-=1
        if data[start]>data[i] :
            data[start],data[i]=data[i],data[start]
        quickly_sorted(data[0:i])
        quickly_sorted(data[i+1:])
data=[6,2,4,5]
quickly_sorted(data)

同时 我在网上还看到一些人,在交换元素位置的时候,不是利用data[start],data[i]=data[i],data[start] 而是利用列表中pop()和append()方法,这虽然满足快速排序的某些条件,但是这时间复杂度不是O(nlogn),因为pop()和append()这两个方法的时间复杂度为O(n),所以整体的时间复杂度为O(n^2),所以不满足‘快速’二字.

原创不易,转载请注明出处。


 

猜你喜欢

转载自blog.csdn.net/MG1723054/article/details/85523995