這裏寫自定義目錄標題
一、分而治之
假設你是農場主,有一小塊土地。你要將這塊地均勻地分成方塊,且分出的方塊要儘可能大。
顯然,下面的分法都不符合要求。
如何將一塊地均勻地分成方塊,並確保分出的方塊是最大的呢?
使用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]
其實對於基準值的選擇,無論選擇誰作爲基準值都可以分別把小於基準值合成一個數組(可以爲空數組),大於基準值的一個數組(可以爲空數組),最終都可以用快速排序法進行排序。