算法圖解第四章快速排序(遞歸的巧妙應用)(學習筆記)

一、分而治之

假設你是農場主,有一小塊土地。你要將這塊地均勻地分成方塊,且分出的方塊要儘可能大。

顯然,下面的分法都不符合要求。
在這裏插入圖片描述

如何將一塊地均勻地分成方塊,並確保分出的方塊是最大的呢?

使用D&C策略!D&C算法是遞歸的。

使用D&C解決問題的過程包括兩個步驟。

(1)找出基線條件,這種條件必須儘可能簡單。

(2) 不斷將問題分解(或者說縮小規模),直到符合基線條件。

這裏我就用我畫的圖解釋下:
在這裏插入圖片描述

畫的圖可能不是很標準,你就當這裏面都是正方形,我是怎麼畫的呢?

第一步:首先是一個矩形,既然讓我們儘可能的畫方塊最大的,在矩形裏要想畫最大的正方形,就是讓正方形的邊長最長,正方形的邊長最長不能超過矩形的的寬,所以,第一步就是畫的那兩條黑線。

第二步:畫兩條黑線還剩下一個矩形,跟第一步一樣,繼續使正方形的邊長最長,就是畫的那兩條紫色線。

第三步:最後一個的矩形的長等於寬的兩倍,所以正好是兩個正方形。

而使用D&C解決問題的過程包括兩個步驟:

(1) 找出基線條件,而這裏的基線條件就是當長等於寬的兩倍時

(2) 不斷將問題分解(或者說縮小規模),直到符合基線條件。再這裏每次分開最大正方形後會留下一個矩形,而這個矩形再重複原來的步驟即可。

二、快速排序

如何對一個數組進行快速排序呢?

快速排序也是用了D&C,所以必須先理解上面那個例子。

下面我們就來學習快速排序。

對一個數組進行快速排序,先找出基線條件,也就是最簡單的數組,也就是不用排序的數組。所以:

基線條件:數組爲空或者只包含一個元素(因爲這樣只需要原樣返回數組即可,不用排序)

如果有多個元素的數組怎麼辦?

你就要使用D&C,將數組分解,直至滿足基線條件,到這裏D&C解決問題的過程的兩個步驟基本確定了。

下面就介紹快速排序的工作原理:

首先,從數組中選擇一個元素,這個元素被稱爲基準值

稍後再介紹如何選擇合適的基準值。我們暫時將數組的第一個元素用作基準值

接下來,找出比基準值小的元素以及比基準值大的元素,分別位於基準值兩邊,如圖:
在這裏插入圖片描述

現在你有:

(1)一個由所有小於基準值的數字組成的子數組(可以爲空);

(2)基準值;

(3)一個由所有大於基準值的數組組成的子數組(可以爲空)。

但是這裏只是進行了分區,得到的兩個子數組是無序的

而如果這兩個數組是有序的,對整個數組進行排序將非常容易。

只需要像這樣:左邊的數組 + 基準值 + 右邊的數組,合併就可以了。

所以只要對這兩個子數組進行快速排序,再合併結果,就能得到一個有序數組!

而這兩個子數組不就又可以當成原來的那個數組去重複以上的步驟。)

三、快速排序的代碼:

def sort(a):
    if len(a)<2:
        return a  #基線條件:爲空或只包含一個元素的數組是“有序”的
    else:
        x=a[0]
        less=[i for i in a[1:] if i <=x]  #由所有小於基準值的元素組成的子數組
        more=[i for i in a[1:] if i >x]   #由所有大於基準值的元素組成的子數組
        return sort(less)+[x]+sort(more)  #左邊的數組(有序) + 基準值 + 右邊的數組(有序)
print (sort([5,4,2,9,3,8,6,2,1,5]))

結果:

[1, 2, 2, 3, 4, 5, 5, 6, 8, 9]

其實對於基準值的選擇,無論選擇誰作爲基準值都可以分別把小於基準值合成一個數組(可以爲空數組),大於基準值的一個數組(可以爲空數組),最終都可以用快速排序法進行排序。

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