快速排序
定義
快速排序(Quicksort),又稱分割槽交換排序(partition-exchange sort),簡稱「快排」,是一種被廣泛運用的排序演算法。
過程
快速排序的工作原理是透過 分治 的方式來將一個陣列排序。
快速排序分為三個過程:
1.將數列劃分為兩部分(要求保證相對大小關係);
2.遞迴到兩個子序列中分別進行快速排序;
3.不用合併,因為此時數列已經完全有序。
和歸併排序不同,第一步並不是直接分成前後兩個序列,而是在分的過程中要保證相對大小關係。具體來說,第一步要是要把數列分成兩個部分,然後保證前一個子數列中的數都小於後一個子數列中的數。為了保證平均時間複雜度,一般是隨機選擇一個數 m 來當做兩個子數列的分界。
之後,維護一前一後兩個指標 p 和 q,依次考慮當前的數是否放在了應該放的位置(前還是後)。如果當前的數沒放對,比如說如果後面的指標 q 遇到了一個比 m 小的數,那麼可以交換 p 和 q 位置上的數,再把 p 向後移一位。當前的數的位置全放對後,再移動指標繼續處理,直到兩個指標相遇。
其實,快速排序沒有指定應如何具體實現第一步,不論是選擇 m 的過程還是劃分的過程,都有不止一種實現方法。
第三步中的序列已經分別有序且第一個序列中的數都小於第二個數,所以直接拼接起來就好了。
模板
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
程式碼實現
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
return 0;
}