快速排序算法

快速排序算法

基本思想

快速排序是一類交換排序,它是對起泡排序的一種改進.它的基本思想是, 通過一趟排序將待排記錄分割成獨立的兩個部分, 其中一部分記錄的關鍵字均比另一部分的關鍵字小, 然后再分別對這兩個部分繼續進行快速排序, 以達到整個序列有序的目的.

快速排序的工作過程

  1. 在數組中選擇一個關鍵字作為樞紐(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

  2. 劃分待排數組元素, 將小于pivot的記錄放在pivot的左邊, 大于pivot的記錄放在pivot的右邊

  3. 重復上述兩個步驟, 直到每個劃分中的記錄個數小于2, 此時待排數組有序, 快速排序算法執行完畢

這里以整型數組A[] = {49, 38, 65, 97, 76, 13, 27} 為例, 演示一趟快速排序算法的執行過程, 即對待排數組的劃分過程

選擇38作為pivot, 此時數組A的初始狀態如下


pivot.png

如果A[low] < pivot, low++
如果A[high] > pivot, high--
如果A[low] >= pivot, A[high] <= pivot, 交換A[low]與A[high]的位置


partition.png

快速排序算法實現

/**
 選擇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);
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容