首页 > 代码库 > 快速排序 python

快速排序 python

    说到快速排序,真的花了很大的功夫去看,去理解。排序算法是挺复杂的,理解它就好像是剥洋葱一样,一层一层的。好了,下面说说快排的原理吧。

    快速排序就像很多网上的文章一样,是分而治之的,通过递归的方式不断的分而治之。每递归一次就找到当前的标杆值将比这个值大的所有数放到标杆值的右边,小的放到左边,然后再分别对标杆值左边和右边的两个子数组进行同样的函数操作。

    快排最最核心的地方就是找到每次标杆值所处的位置。有以下几个步骤:

        1. 挑选出一个标杆值key,一般选择数组的第一个值

        2. 一个for循环,从第二个数开始遍历数组,每一个数都和这个key进行对比

        3. 遍历的目的是给这个标杆值key找到合适的位置(即小的在都在左边,大的都在右边),通过求出比标杆值小的数的个数m;当然还需要将大的值移动到后面去。

        4. 如果数组的a[i] < key,m++;如果m 不等于当前的位置 i,则说明 a[i] 这个值比key大,需要移动到后面去;移动不断的交换完成。

        5. 快排最难理解的地方应该就是移位交换了,也就是partition部分。遍历的时候 i 的值是从1到end的递增,而 m则保存了标杆值的位置a[m]。

            假设a[i] 一直都比key小的话,则m和 i会是一样的,因为到最后一步的时候,a[m] 会和 a[0] 对换位置,因为a[m] 的值是比key小的,所以对换位置后 ,标杆值放到的应在的位置,而a[m]的值比key小,放到第一个也是没错的。

            当 a[i]的值比key大时,m不能再增加1和 i一样了, 因为要对换位置的。如果下一轮比较仍然是a[i] 比key大,则m 继续不变( m 位置一直都是临界位置,后面就是比key大的);直到有比key小的数出现,m再增加 1 ,将那个数‘解救’回来。交换 a[m]和 a[i] 的值,将比key大的值放到后面,把比key小的值移动到a[m]的位置。依次类推。。

            

            遍历数组partition的过程的精华,就在于这个m,它既能够通过计数得到key的位置,还可以将比key小的数从比key大的数的后面“解救”回来,从而将 ‘大小值‘ 分离。


    6. 当移动完成后,比key大的值都移动到后面,比key小的值都移动到前面来,此时 m 的位置就是临界点,后面就是比key大的,然后再交换key值所在的a[0] 和a[m],则完成这一次的partition。

    7. 接下来就是递归了。分别将比key小的和比key值大的数当做输入数组,放到两个同样的函数中,再次回到步骤1。


    

    网上有很多动态的图:

    技术分享

    

    接下来是python的具体实现:

    

#!/usr/bin/python

a = [5,1,4,9,8]


def Quick_sort(us_list, low, high):
    
    if (low < high):

        mid = _Partition(us_list, low, high)
        Quick_sort(us_list, low, mid-1)
        Quick_sort(us_list, mid+1, high)

def _Partition(us_list, low, high):
    
    mid = low 
    mid_value = us_list[low]

    for i in range(low+1, high+1):
    
        if (a[i] < mid_value):
            mid += 1
            if mid != i:
                t = us_list[mid]
                us_list[mid] = a[i]
                a[i] = t 
        print a[mid],a[i]
        print a

    t = a[low]
    a[low] = a[mid]
    a[mid] = t 

    return mid 


def main():

    Quick_sort(a, 0, len(a) - 1)

    print a


if __name__ == ‘__main__‘:
    main()

    

快速排序 python