排序 快速排序

2022-08-17 16:27:17 字數 1367 閱讀 3976

時間複雜度 最理想 o(nlogn) 最差時間o(n^2)

像合併排序一樣,快速排序也是基於分治模式的。下面是對乙個典型子陣列a[p..r]排序的分治過程的三個步驟:

分解:陣列a[p..r]]被劃分成兩個(可能空)子陣列a[p..q-1]和a[q+1..r],使得a[p..q-1]中的每個元素都小於等於a(q),而且,小於等於a[q+1..r]中的元素。下標q也在這個劃分過程中進行計算。

解決:通過遞迴呼叫快速排序,對子陣列a[p..q-1]和a[q+1..r]排序。

合併:因為兩個子陣列是就地排序的,將它們的合併不需要操作:整個陣列a[p..r]已排序

快速排序:

quicksort(a,p,r)

if pthen q=partition(a,p,r)

quicksort(a,p,q-1

) quicksort(a,q+1,r)

陣列劃分:

partition(a,p,r)

x=a[r]

i=p-1

for j=p to r-1

doif a[j]<=x

then i=i+1

exchange a[i]

<->a[j]

exchange a[i+1]<->a[r]

return i+1

可參照c**:

int a[101],n;//

定義全域性變數,這兩個變數需要在子函式中使用

int partion(int left,int

right)

} //最終將基準數歸位

a[left]=a[i];

a[i]=temp;

returni;}

void quicksort(int left,int

right)

選取樞紐元問題

1、糟糕的方法 

通常的做法是選擇陣列中第乙個元素作為樞紐元,如果輸入是隨機的,那麼這是可以接受的。但是,如果輸入序列是預排序的或者是反序的,那麼依據這樣的樞紐元進行劃分則會出現相當糟糕的情況,因為可能所有的元素不是被劃入s1,就是都被劃入s2中。 

2、較好的方法 

乙個比較好的做法是隨機選取樞紐元,一般來說,這種策略是比較妥當的。 

3、三數取取中值方法 

例如,輸入序列為  8, 1, 4, 9, 6, 3, 5, 2, 7, 0 ,它的左邊元素為8,右邊元素為0,中間位置|_left+right)/2_|上的元素為6,於是樞紐元為6.顯然,使用三數中值分割法消除了預排序輸入的壞情形,並且減少了快速排序大約5%(此為前人實驗所得資料,無法具體證明)的執行時間。

參考:舊部落格原文

看演算法:快速排序

排序 快速排序

快速排序時實踐中最快的一直排序,平均時間是0 nlogn 最壞的情況是o n2 但是很容易將這種情況避免 空間複雜度 o n lgn 不穩定。快速排序時基於分治模式處理的,對乙個典型子陣列a p.r 排序的分治過程為三個步驟 1.分解 a p.r 被劃分為倆個 可能空 的子陣列a p q 1 和a ...

排序 快速排序

定義 在快速排序演算法中,使用了分治策略,將要排序的序列分成兩個子串行,然後遞迴地對子序列進行排序,直到整個序列排序完畢。步驟 1.在序列中選擇乙個關鍵元素作為軸 2.對序列進行重新排序,將比軸小的元素移到軸的前邊,比軸大的元素移動到軸的後面。在進行劃分之後,軸便在它最終的位置上 3.遞迴地對兩個子...

排序 快速排序

時間複雜度 快速排序每次將待排序陣列分為兩個部分 1 在理想狀況下,每一次都將待排序陣列劃分成等長兩個部分,則需要logn次劃分。2 在最壞情況下,即陣列已經有序或大致有序的情況下,每次劃分只能減少乙個元素,快速排序將不幸退化為氣泡排序,最壞情況為o n 2 快速排序的平均時間複雜度為o nlogn...