快速排序 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。


    

    網上有很多動態的圖:

    Visual-and-intuitive-feel-of-7-common-so

    

    接下來是python的具體實現:

    

#!/usr/bin/python


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 (us_list[i] < mid_value):
            mid += 1
            if mid != i:
                t = us_list[mid]
                us_list[mid] = us_list[i]
                us_list[i] = t 
        

    t = us_list[low]
    us_list[low] = us_list[mid]
    us_list[mid] = t 

    return mid 


def main():

    a = [5,1,4,9,8]
    
    Quick_sort(a, 0, len(a) - 1)

    print a


if __name__ == '__main__':
    main()

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章