模板 快速排序

2022-08-11 09:06:09 字數 1540 閱讀 1402

給定陣列大小n和陣列q[n],對陣列進行排序。

快速排序的原理:基於分治

(1)確定分界點x:可以取x為q[l], q[l + r >> 1],q[r], 或者陣列中間隨機乙個值(建議取q[l + r >> 1], 原因在後面說)。這裡l和r是當前待排序陣列的左右端點。

(2)重新調整區間,使得調整後的區間,小於等於x的數都在x的左邊,大於等於x的數都在x的右邊(和x相等的數在左邊、右邊都可)。 調整區間的方法有兩種,後面說。

(3)遞迴處理分界點的左右兩段,最後拼接起來的區間就是有序的了。

調整區間的方法(一):

(1)額外開兩個陣列a, b

(2)掃瞄陣列q[l~r],如果當前的數q[i] <= x, 則把q[i]存入陣列a. 即q[i] -> a;

如果當前的數q[i]>=x,則把q[i]存入陣列b. 即q[i] -> b[i];

(3)此時a, b就分別是q的左半部分和右半部分了,把它們的值賦給q. 即a -> q, b -> q。

這種方法的優點是好理解。缺點也顯而易見:空間開銷大。

調整區間的方法(二):

有一種用雙指標來調整區間的優雅的方法。

(1)一開始,我們讓兩個指標i和j分別指向區間的兩個端點l和r;

(2)當q[i] < x時,i向右移動,若找到q[i] >= x,則i停下。 j向左移動,直到i和j相遇或者q[j] <= x;

(3)若i和j未相遇,則i和j此時指向的元素都是錯位的,交換這兩個數的位置:swap(q[i], q[j]);

(4) 重複上面的步驟,知道i和j相遇。

這種劃分區間方法的正確性證明:在任意時刻,左指標i左邊的數都是小於等於x的,j右邊的數都是大於等於x的,當i與j相遇時,

相遇點左邊的數都小於等於x,相遇點右邊的數都大於等於x,故區間調整正確。

這題**如下:

#includeusing namespace std;

const int n = 1e6 + 10;

int q[n];

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

int x = q[l + r >> 1], i = l - 1, j = r + 1; //分界點x最好取中位數q[l + r >> 1],因為如果取邊界q[l]或者q[r],且區間是公升序或降序時,時間複雜度為o(n^2),在這題會超時

while(i < j)

}quick_sort(q, l, j); //遞迴處理左半部分區間

quick_sort(q, j + 1, r); //遞迴處理右半部分區間

}int main()

quick_sort(q, 0, n - 1);

for(int i = 0; i < n; ++i)

return 0;

}

排序 快速排序模板

以某個記錄 元素 為界 該記錄稱為支點或樞軸 將待排序列分成兩部分 一部分 所有記錄的關鍵字大於等於支點記錄的關鍵字 另一部分 所有記錄的關鍵字小於支點記錄的關鍵字 演算法描述 1 任取待排序記錄序列中的某個記錄 例如取第乙個記錄 作為基準 樞 按照該記錄的關鍵字大小,將整個記錄序列劃分為左右兩個子...

快速排序 模板

說明 經過本函式處理後,陣列itemarray中元素滿足prulefunc itemarray itemr itemarray iteml 為true,其中itemr iteml template t void quicksort itemarray,int iteml,int itemr,bool...

模板 快速排序

排序演算法可以說是從語言步入演算法的第一道坎了,其中最有代表性的莫過於快排。這裡模擬庫函式自帶sort的呼叫方式,寫起來相當自然清爽。樸素快速排序演算法的複雜度最好為o nlogn 最壞時能達到o n include include include include include include d...