快速排序(Quicksort)

2021-06-19 07:43:17 字數 1767 閱讀 7868

0)引論

人如其名,快速排序之所以稱之為快速排序就是因為在實踐中,這個演算法是最快的排序演算法。它的平均執行時間為o(nlogn)。最壞的時間複雜度為o(n^2)。雖然像堆排序,歸併排序的時間複雜度比較低,但是他們的實際執行時間並不比快速排序快,反而由於有一些拷貝的程序,使執行時間變得很慢。快速排序也是一種divide-and-conquer策略。

1)快速排序基本步驟:

a) 如果資料集s中的元素個數為0或1,則返回。

b) 選取s中的乙個元素v,我們稱這個元素v為pivot。

c) 把s-分成兩部分s1 = ,s2 = 。

d) 返回quicksort(s1) , v, quicksort(s2)。

2)pivot的選擇

pivot的選擇是乙個很大的問題。因為pivot直接影響到分開的兩組資料的個數,而如果這兩組資料是不均衡的,則會嚴重影響到演算法的執行速度。舉個例子來說,如果每次選擇的pivot 都是最大值的話,那麼這個快速排序演算法相當於插入排序

pivot的選擇有以下幾種

a) 選取第乙個值。這種演算法適用於隨機分布的資料。如果是乙個有序的序列,那麼這種選取方式就是乙個災難啊,將會不斷的遞迴,也沒有什麼本質的提高

b) 隨機選取乙個值。這種方法也是看運氣,如果選擇了乙個好的值就沒有問題。但是如果選的值比較差,就會比較糟糕

c) 隨機選取3個值,取中間值。這種方法對差值的風險抵抗能力比較強。一種常用的方法是選擇資料的第乙個值,中間的值,最後乙個值。然後取這3個值得中間值。

**片段:

elementtype median3(elementtype a, int left, int right)

3)演算法描述

這裡,我們通過乙個例子說明一下快速排序演算法。

待排序資料為(8,34,51,21,18,64,26,32)首先利用上面的方法找到pivot為21,然後把pivot與a[n-1]=26交換位置。然後設定兩個游標i,j。i向右滑動直到遇到大於pivot的值處停止,j向左滑動直到遇到小於pivot的值處停止,然後交換i,j對應的元素,然後繼續上面的步驟知道i>j,然後交換i與pivot對應的元素。這樣就把待排序資料集分成了兩部分,然後遞迴呼叫上面的演算法,最終得到排好序的資料。這裡可能會有乙個問題就是相等的元素,這將是乙個特殊情形,例如資料中有幾個值與pivot相等,那麼當游標運動到了這幾個位置時應該怎麼辦呢?游標繼續向前走,越過這些值。

**描述:

#define cutoff (3)

void qsort(elementtype a, int left, int right)

if(i

4)到底應該選取什麼樣的排序演算法

我們已經介紹了幾種排序方法,那麼到底應該怎樣選取排序方法呢?如果排序數目比較大,那麼盡量用快速排序,如果資料量比較小,還是用插入排序或希爾排序比較好,因為這個兩種方法比較簡單,更重要的是在小資料量的排序中,快速排序的遞迴運算更加耗時。如果資料量相當大以至於無法完全在記憶體中執行,那麼建議用歸併排序,歸併排序主要應用於外部排序中。當然還有一種桶排序,這個排序的速度相當迅速,但是限制條件太多,要求待排序資料為不大於某一值得正整數,約束性太強了。

5)排序方法的下界

任何只利用比較方法來排序的方法的最壞情況下需要

快速排序 QuickSort

快速排序通常用於排序的最佳的使用選擇,其期望執行時間為 o nlgn 能夠進行就地排序。最壞執行時間為 o n 2 演算法描述 分解 divide 陣列 a beg end 被劃分為兩個子陣列 a beg mid 1 和a mid 1 end 使得a beg mid 1 中的資料都小於 a mid ...

快速排序 quicksort

快速排序 quicksort 是分治法的典型例子,它的主要思想是將乙個待排序的陣列以陣列的某乙個元素x為軸,使這個軸的左側元素都比x大,而右側元素都比x小 從大到小排序 然後以這個x在變換後陣列的位置i分為左右兩個子陣列,再分別進行快速排序,直到子陣列中只有乙個元素為止。快速排序演算法如下 void...

快速排序 QuickSort

1,void quicksort int a,int low,int high 這個函式是排序的遞迴部分,mid就是已經確定的基準元素的位置。2,int partition int a,int low,int high 這個函式幹了兩件事 1 挑出來乙個基準元素 這裡選的是最後乙個作為基準 找它的正...