快速排序演算法的幾種實現

2021-08-01 04:41:54 字數 1426 閱讀 9347

序列範圍[l,u]

選取第乙個元素為樞紐值,然後圍繞t劃分陣列:

m=a-1

for i =[a,b]

if x[i]

迴圈終止後有:

此時交換x[l]和x[m]即可。

**:void qsort1(int *x, int l, int u)

swap(x[l], x[m]);

qsort(x, l, m - 1);

qsort(x, m + 1, u);

}

可以通過qsort1(0,n-1)來排序陣列x[n]

qsort1函式能夠快速完成隨機序列的排序,但是對於序列由n個相同的元素組成時,效能就非常差,從**中我們可以看出,當序列元素相同時,qsort1的時間複雜度為o(n²)。

使用雙向劃分可以解決這個問題。

對於上面的快速排序,我們可以稍微改進:

**:

void qsort2(int *x, int l, int u)

qsort2(x, l, m - 1);

qsort2(x, m + 1, u);

}

通過將從左到右的迴圈修改為從右向左,從而省去一次swap:

最後一次迴圈結束前:

使用雙向劃分的快速排序:

i指示小於等於t的增長邊界,j指向大於等於t的增長邊界。

**:

void qsort3(int *x, int l, int u)

swap(x[l], x[j]);

qsort3(x, l, j - 1);

qsort3(x, j + 1, u);

}

當while(1)迴圈結束時,序列變成:

所以最後進行swap(x[l],x[j])。

這裡特別要注意i和j,swap的是x[j]不是x[i]!!!

我們注意到:

while (++i <= u && x[i] < t);

while (x[j] > t);

為什麼第二個while不寫成while (--j >= l && x[j] > t)?因為沒有必要,序列的第乙個元素為t,當j==l時有x[j]==t,該迴圈總是能終止不會發生越界情況(相當於第乙個元素為哨兵),而第乙個while則不同。

當遇到和t相同的元素時,停止掃瞄並交換x[i]和x[j],這樣做雖然交換的次數增加了,但卻將所有元素相同的最壞情況變成了差不多需要nlogn次比較的最好情況。

但是,如果序列已經排好序了,上面的**效能依然會下降到o(n²),原因是我們每次都是選擇第乙個元素作為劃分元素。我們可以通過隨機選擇劃分元素來解決:

int c=randint(l,u);

swap(x[l],x[c]);

其中函式randint(l,u)產生[l,u]之間的隨機數。

幾種快速的排序演算法

鴿巢排序,排序位元組串 寬位元組串最快的排序演算法,計數排序的變種 將計數緩衝區大小固定,少一次遍歷開銷 速度是stl中std sort的20多倍 更重要的是實現極其簡單!缺點是需要乙個size至少等於待排序陣列取值範圍的緩衝區,不適合int等大範圍資料。多一次遍歷的計數排序,排序位元組串的話速度約...

快速排序演算法的幾種版本及實現

寫在前面的話 最近系統地學習了快速排序演算法,在此作一筆記。主要包括快排的各種版本 普通版本,改進的普通版本,隨機化版本,三數值取中分割版本和stooge版本。對各版本進行了簡要分析,並給出了具體實現。演算法導論 對快排的描述 快速排序是基於分治模式的,下面是對乙個典型子陣列a p.r 排序的分治過...

幾種排序演算法 (快速排序 堆排序)

快速排序 include usingnamespacestd voidqsort inta,intlow,inthigh intfirst low intlast high intkey a first 用字表的第乙個記錄作為樞軸 while first last a first a last 將比...