快速排序詳解

2021-08-02 17:53:05 字數 1728 閱讀 4409

快速排序法詳解

快速排序法(quicksort)是一種非常快的對比排序方法。它也divide-and-conquer思想的實現之一。自從其產生以來,快速排序理論得到了極大的改進,然而在實際中卻十分難以程式設計出正確健壯的**。本文將對快速排序演算法的基本理論和程式設計實踐方面做作乙個全面的講解。在本文講解中,將忽略很多細枝末節,試圖給讀者形成乙個非常具體的快速排序形象。

1.快速排序—基本理論

因為該演算法是divide-and-conquer思想的乙個實現,所以本文將以divide-and-conquer思想對其進行分析。首先,假設所要排序的數字儲存在陣列s中,則該演算法的操作可以拆分為兩部分:

在s中選出乙個元素v;

將s陣列分為三個子陣列。其中v這個元素單獨形成子陣列1,比v小的元素形成子陣列2,比v大的元素形成自陣列3.

分別對子陣列2和子陣列3進行前兩步操作,實現遞迴排序;

返回時,依次返回s1,v,s2;

該程式具有平均執行時間t(n) = o(nlgn), 最差執行時間t(n) = o(n^2);

下面給出乙個簡單的排序例項對以上演算法進行簡單說明:

初始陣列為————–> s: 6,10,13,5,8,3,2,11

將第乙個元素賦值給v—–>v = 6;

以v為標準將s進行拆分—>[2,5,3],[6],[8,13,10,11] <———-將得到的陣列命名為s1, s2;

同樣對子陣列s1進行拆分->[ ], [2], [ 5, 3] <——————–拆分之後,第乙個子陣列為空。將得到的陣列命名為s12;

對子陣列s2進行拆分—–>[ ], [8], [13, 10, 11]<—————將得到的陣列命名為s22;

此時的陣列s為———->2,5,3,6,8,13,10,11

對子陣列s12進行拆分—->[3], [5],[ ];

對自陣列s22進行拆分—->[10,11],[13],<——————–將得到的陣列命名為s221

此時的陣列s為———–>2,3,5,6,8,10,11,13

對子陣列s221進行拆分—>[ ], [11], [13]

對後得到的陣列為——–>2,3,5,6,8,10,11,13;

根據以上分析,編寫快速排序演算法程式,得到的程式如下:

複製**

#include 

#include

using

namespace::std;

int partition( int a, int p, int q ) }

swap(a[p], a[i]);

return i;

} void quicksort( int a, int p, int q ) }

int main()

; quicksort(a,0,9);

for( int k = 0; k < 10; k++ )

cout

<< a[k] << " ";

cout

<< endl;

}

複製**

計算結果如圖:

看似結果很好,但是很遺憾,在實際中,我們卻並不採用這樣的程式。為什麼呢?因為該程式還有幾點需要進行改進:

當我們輸入的陣列s是已經排序好的一列數,那麼這個程式的執行時間將是o(n^2),這個效率是插入排序的效率,所以是很低很低的。(可以利用遞迴樹進行具體分析)

為了提高效率,可以使得i和j分別從左邊和右邊進行搜尋,將值分別與v進行對比,當s[i]>v而s[j]

快速排序詳解

快速排序也是基於交換的原理進行的,是對氣泡排序的一種改進。即它是通過不斷比較和移動交換來實現排序的,只不過它的實現,增大了記錄的比較和移動的距離,將關鍵字比較大的記錄從前面直接移動到後面,關鍵字較小的記錄從後面直接移動到前面,從而減小了總的比較次數和移動次數。快速排序是找出乙個元素 理論上可以隨便找...

快速排序詳解

對於陣列s 2,1,3,0,4,5,8,7,1 進行排序 最好的情況是val每一次取到中間值,則複雜度為nlog n 最壞的情況是val每一次取到最小值或者最大值,則複雜度為n 2 include include include include include include include inc...

快速排序 詳解

注 如果下面不詳細,可以去這個連線看我記錄下的筆記 概念 快速排序其實是 二分 的應用。雖然類似於冒泡,但是它比冒泡的跳躍更大。樣例 int arr 10 第一步 確定arr 0 為基準數。第二步 先從最右邊 arr 9 開始讀取數字,讀到比基準數小的時候。再從基準數開始讀取。讀到比基準數大的時候,...