白話經典演算法系列之六 快速排序 快速搞定

2022-03-29 14:43:09 字數 2036 閱讀 7104

總的說來,要直接默寫出快速排序還是有一定難度的,因為本人就自己的理解對快速排序作了下白話解釋,希望對大家理解有幫助,達到快速排序,快速搞定。

快速排序是c.r.a.hoare於2023年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(divide-and-conquermethod)。

該方法的基本思想是:

1.先從數列中取出乙個數作為基準數。

2.分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。

3.再對左右區間重複第二步,直到各區間只有乙個數。

雖然快速排序稱為分治法,但分治法這三個字顯然無法很好的概括快速排序的全部步驟。因此我的對快速排序作了進一步的說明:挖坑填數+分治法:

先來看例項吧,定義下面再給出(最好能用自己的話來總結定義,這樣對實現**會有幫助)。

以乙個陣列作為示例,取區間第乙個數為基準數。01

2345

6789

7265788

6042

8373

4885

初始時,i = 0;  j = 9;   x = a[i] = 72

由於已經將a[0]中的數儲存到x中,可以理解成在陣列a[0]上挖了個坑,可以將其它資料填充到這來。

從j開始向前找乙個比x小或等於x的數。當j=8,符合條件,將a[8]挖出再填到上乙個坑a[0]中。a[0]=a[8]; i++;  這樣乙個坑a[0]就被搞定了,但又形成了乙個新坑a[8],這怎麼辦了?簡單,再找數字來填a[8]這個坑。這次從i開始向後找乙個大於x的數,當i=3,符合條件,將a[3]挖出再填到上乙個坑中a[8]=a[3]; j--;

陣列變為:01

2345

6789

4865788

6042

8373

8885

i = 3;   j = 7;   x=72

再重複上面的步驟,先從後向前找,再從前向後找

從j開始向前找,當j=5,符合條件,將a[5]挖出填到上乙個坑中,a[3] = a[5]; i++;

從i開始向後找,當i=5時,由於i==j退出。

此時,i = j = 5,而a[5]剛好又是上次挖的坑,因此將x填入a[5]。

陣列變為:01

2345

6789

4865742

6072

8373

8885

可以看出a[5]前面的數字都小於它,a[5]後面的數字都大於它。因此再對a[0…4]和a[6…9]這二個子區間重複上述步驟就可以了。

對挖坑填數進行總結

1.i =l; j = r; 將基準數挖出形成第乙個坑a[i]。

2.j--由後向前找比它小的數,找到後挖出此數填前乙個坑a[i]中。

3.i++由前向後找比它大的數,找到後也挖出此數填到前乙個坑a[j]中。

4.再重複執行2,3二步,直到i==j,將基準數填入a[i]中。

照著這個總結很容易實現挖坑填數的**:

int adjustarray(int s, int l, int r) //返**整後基準數的位置

// 從左向右找大於或等於x的數來填s[j]

while(i < j && s[i] < x)

i++; 

if(i < j)

}//退出時,i等於j。將x填到這個坑中。

s[i] = x;

return i;

再寫分治法的**:

void quick_sort1(int s, int l, int r)

//快速排序

void quick_sort(int s, int l, int r)

s[i] = x;

quick_sort(s, l, i - 1); // 遞迴呼叫

quick_sort(s, i + 1, r);

}快速排序還有很多改進版本,如隨機選擇基準數,區間內資料較少時直接用另的方法排序以減小遞迴深度。有興趣的筒子可以再深入的研究下。

注1,有的書上是以中間的數作為基準數的,要實現這個方便非常方便,直接將中間的數和第乙個數進行交換就可以了。

白話經典演算法系列之 快速排序 快速搞定

總的說來,要直接默寫出快速排序還是有一定難度的,因為本人就自己的理解對快速排序作了下白話解釋,希望對大家理解有幫助,達到快速排序,快速搞定。快速排序是c.r.a.hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法 divide and conquermethod ...

白話經典演算法系列

堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆的定義二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都...

經典演算法系列一 快速排序

寫乙個系列的經典演算法,共同學習!1.快速排序 基本思想 1.先從數列中取出乙個數作為基準數。2.分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。3.再對左右區間重複第二步,直到各區間只有乙個數。在網上看到一篇部落格,把快速排序命名為 挖坑填數 分治法,感覺很有道理,所以...