排序演算法之快速排序

2021-09-25 04:42:56 字數 1414 閱讀 5196

分治法,將大問題分為若干個小的問題,解決小問題然後合成大問題的解

1、在陣列中找到乙個數,一般選作陣列最後乙個數作為中軸數x

2、以中軸數x作為中心,使用一次劃分partition,使得中軸數左邊的數都比x小,右邊的數都比x大,換句話說經歷過一次劃分後,中軸數x處在它本來應該在的位置上

3、遞迴呼叫partition,最後使得整個陣列有序

1

int partition(int data,int start,int

end)10}

11 exchange(data+i+1,data+end);

12return i+1; //

i標識的是陣列中值小於x的最大下標,i+1即指一次劃分後x所在的下標位置

13 }

1

void quicksort(int data,int start,int

end)

7 }

注:函式的邊界檢查條件可以交付給上層呼叫函式來完成

上述為了簡便說明,總是選取待排序陣列的最後乙個元素作為中軸數,假設一種極端的情況,待排陣列已經有序或者元素值全部相同,進行一次partition劃分後,中軸數左右兩邊的元素個數分別是n-1,0,即每經過一次劃分,就僅僅將乙個陣列元素放置在它應該在的位置上,剩餘的n-1個數還需要繼續排序,每次劃分的時間複雜度為遍歷一次待排陣列所消耗的時間o(n)

設整個排序的時間複雜度為t(n),則最壞的情況下,t(n)=t(n-1)+t(0)+o(n),可以遞推得t(n)=o(n^2)

演算法的最佳時間複雜度,在最理想的情況下,每次劃分總是將待排陣列均衡劃分,即一次劃分完成後,中軸數左右兩邊的元素個數都是(n-1)/2,則其總的時間複雜度

t(n)<=2*t(n/2)+o(n),t(n)=o(nlgn)

演算法的平均時間複雜度,t(n)=o(nlgn),(任何一種按常數比例進行的劃分都會產生深度為o(lgn)的遞迴樹,每一層的時間複雜度為進行一次劃分的時間o(n),所以總的時間複雜度是o(nlgn)----演算法導論),可以理解為,如果某一層的劃分效果比較差,則該層下面的劃分可能會比較好,好差劃分隨機的分布在遞迴樹的各層,總的劃分漸進於每層都是情況好的劃分。

由快排的三個過程可以知道,快排不是一種穩定的排序,例如[2,5,6,4(1),7,3,8,4(2)],經歷一次劃分後,陣列變為[2,3,4(2),4(1),7,5,8,6],括號標識第1和第2個4.

快速排序對於輸入陣列的隨機性有要求,如果待排序的陣列元素具有較大的隨機性,則排序效果接近於基於比較的排序方法的下限o(nlgn),如果輸入的陣列基本有序,則不適用於快速排序。

因此,對於待排序陣列,可以給出快排的隨機化版本,每次在劃分之前,在陣列中隨機選擇乙個數t和陣列中最後乙個數x交換位置,交換過後呼叫上述partition函式,從而將隨機選擇的元素t作為中軸數,從而優化排序的效能。

排序演算法之快速排序

快速排序使用分治法 divide and conquer 策略來把乙個序列 list 分為兩個子串行 sub lists 步驟為 從數列中挑出乙個元素,稱為 基準 pivot 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面 相同的數可以到任一邊 在這個分割槽退出...

排序演算法之快速排序

快速排序入口 public void quicksort int lists 遞迴呼叫該函式。原理 每次從陣列從選乙個標兵 本實現為簡單起見直接選取給定範圍內的第乙個元素為標兵 讓後在給定範圍內進行雙向遍歷,目的是以標兵為分界線,將所有小於標兵值的數字排一邊,將所有大於標兵的數字 放到另一邊。標兵移...

排序演算法之快速排序

快速排序是一種不穩定的排序演算法,它的基本思想是,以某個元素為基準,將所有大於等於它的值放在右邊,小於它的值放在左邊,這樣陣列就被分為兩部分,遞迴對這兩部分進行快速排序,而單個元素我們認為是已經排好序的。這是一種歸併思想,當然在最後一步,合併,我們什麼也沒有做也不用做。每一次排序都有乙個元素被放在正...