5. 快速排序
阿新 • • 發佈:2018-09-04
nbsp 個數 void 排序 com return swa quic turn
一、基本思想
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以使整個序列有序。
在分割的過程中,樞紐元的選擇至關重要。原因如下:
(1)兩部分數據是以樞紐元為分界點,小於等於樞紐元的數全部放在樞紐元的左邊,而大於等於樞紐元的數全部放在樞紐元的右邊;
(2)一般選用左端、右端和中心位置上的三個元素的中值作為樞紐元,即三數取中法,它可以很大程度上避免分組“一邊倒”的情況。
二、三數取中
在快排的過程中,每一趟排序我們都要取一個元素作為樞紐值,以這個數字來將序列劃分為兩部分。
在此我們采用三數取中法,也就是取左端、中間、右端三個數,然後進行排序,將中間數作為樞紐值。
三、根據樞紐值進行分割
四、代碼
/* 快速排序 */ void QuickSort(int a[], int left, int right) { if(left >= right) return; // 采用三數取中法,獲取樞紐元,並將其放在當前待處理序列末尾 DealPivot(a, left, right); int pivot = a[right-1]; // pivot為樞紐元,而其下標為right-1 int i = left, j = right - 1; // 設置兩個遊標,用以標記待排序區間 // 當 i = j 時,已經查找完整個區間了 while(i != j) { while(i < j && a[i] <= pivot) // 因為樞紐元在右邊,所以從左邊開始 ++i; while(i < j && a[j] >= pivot) --j; if(i < j) swap(a[i], a[j]); } // 此時 i = j swap(a[i], a[right-1]); sort(a, left, i-1); sort(a, i+1, right); } // 處理樞紐元 void DealPivot(int a[], int left, int right) { int mid = (left + right) / 2; if(a[left] > a[mid]) swap(a[left], a[mid]); if(a[left] > a[right]) swap(a[left], a[right]); if(a[mid] > a[right]) swap(a[mid], a[right]); swap(a[mid], a[right-1]); // 將樞紐元放到倒數第二個元素去,所以要先從左邊檢索 }
5. 快速排序