快速排序算法
基本思想
快速排序是一類交換排序,它是對起泡排序的一種改進.它的基本思想是, 通過一趟排序將待排記錄分割成獨立的兩個部分, 其中一部分記錄的關鍵字均比另一部分的關鍵字小, 然后再分別對這兩個部分繼續進行快速排序, 以達到整個序列有序的目的.
快速排序的工作過程
-
在數組中選擇一個關鍵字作為樞紐(pivot)
這里pivot的選擇對快速排序算法的性能啟關鍵性的影響
當每次選中的pivot在執行完一趟快速排序后, 都能使數組中大致一半的記錄在pivot的左邊, 另一邊在pivot的右邊, 此時快速排序算法的執行效率最高, 時間復雜度為O(nlogn)
當每次選中的pivot在執行完一趟快速排序后, 都使數組中除pivot外的所有記錄都在pivot的一邊時, 快速排序算法的執行效率最低, 時間復雜度為O( n^2 )選擇pivot的常用方式
選擇待排數組的第一個數left和最后一個數right, center = (left + right) / 2, 這里的left, center, right為數組中記錄的下標值; 選擇center位置的記錄為pivot 劃分待排數組元素, 將小于pivot的記錄放在pivot的左邊, 大于pivot的記錄放在pivot的右邊
重復上述兩個步驟, 直到每個劃分中的記錄個數小于2, 此時待排數組有序, 快速排序算法執行完畢
這里以整型數組A[] = {49, 38, 65, 97, 76, 13, 27}
為例, 演示一趟快速排序算法的執行過程, 即對待排數組的劃分過程
選擇38作為pivot, 此時數組A的初始狀態如下
如果A[low] < pivot, low++
如果A[high] > pivot, high--
如果A[low] >= pivot, A[high] <= pivot, 交換A[low]與A[high]的位置
快速排序算法實現
/**
選擇pivot并將pivot放到right - 1位置
@param A 待排數組
@param left 左邊序號
@param right 右邊序號
*/
int Median3(ElementType A[], int left, int right) {
int center = (left + right) / 2;
if (A[left] > A[center]) {
Swap(&A[left], &A[center]);
}
if (A[left] > A[right]) {
Swap(&A[left], &A[right]);
}
if (A[center] < A[right]) {
Swap(&A[center], &A[right]);
}
Swap(&A[center], &A[right - 1]);
return A[right - 1];
}
/**
快速排序
@param A 待排數組
@param left 左邊序號
@param right 右邊序號
*/
void QuickSort(ElementType A[], int left, int right) {
int pivot = Median3(A, left, right);
int i = left;
int j = right - 1;
for (; ; ) {
while (A[++i] < pivot) {}
while (A[--j] > pivot) {}
if (i < j) {
Swap(&A[i], &A[j]);
} else {
break;
}
}
Swap(&A[i], &A[right - 1]);
QuickSort(A, left, i - 1);
QuickSort(A, i + 1, right);
}