1.快速排序簡介
對於包含n個數的輸入數組來說,快速排序是一種最壞情況時間複雜度爲O(n的平方)的排序算法.雖然最壞情況時間複雜度很差,但是快速排序通常是實際排序應用中最好的選擇.因爲他的平均性能非常好,它的期望時間複雜度是O(n lg n),而且其中包含的常數因子非常小.
2.快速排序的原理
快速排序與歸併排序已有,也使用分治思想.下面介紹下對一個典型的子數組A[p..r]進行快速排序的三步分治過程:
分解:數組A[p..r]被劃分爲兩個(可能爲空)子數組A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一個元素都小於等於A[q],而A[q]也小於等於A[p..q-1]中的每個元素,其中,計算下標q也是劃分過程的一部分.
解決:通過遞歸調用快速排序,對子數組A[p..q-1]和A[q+1..r]進行排序.
合併:因爲子數組都是原址排序的,所以不需要合併操作:數組A[p..r]已經有序.
通俗點講就是把數組根據一個參照值劃分爲兩部分,左邊部分小於等於參照值,右邊部分大於等於參照值,然後再不斷遞歸調用該方法,直到數組只有一個元素,就認爲其是有序的.注意:劃分過程,左邊部分和右邊部分可以是不均衡的.
3.java代碼實現,代碼中關鍵代碼都有註釋
//將數組排序成滿足數組左邊比中間值小,右邊比中間值大的方法
int partition(int arr[], int left, int right)
{
int i = left, j = right;
int tmp;
//定義參照值爲數組的中間值
int pivot = arr[(left + right) / 2];
while (i <= j) {
//當arr[i]小於參照值時,符合左邊小的原則,不需調換位置,直接跳過,直到找到不滿足條件的A[i]時終止該循環
while (arr[i] < pivot)
i++;
//當arr[j]大於參照值時,符合右邊大的原則,不需調換位置,直接跳過,直到找到不滿足條件的A[j]時終止該循環
while (arr[j] > pivot)
j--;
//i小於j時,完成a[i]和a[j]的交換
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
//返回的i就是滿足i左邊的值比i小.i右邊的值比i大
return i;
}
void quickSort(int arr[], int left, int right) {
int index = partition(arr, left, right);
// System.out.println("index"+index);
if (left < index - 1){
quickSort(arr, left, index - 1);
// System.out.println(Arrays.toString(arr));
}
if (index < right){
quickSort(arr, index, right);
// System.out.println(Arrays.toString(arr));
}
}
@Test
public void testQuickSort(){
int a[] = {222,5, 2, 4, 6, 1, 3, 11, 9, 10, 8, 7,0};
quickSort(a,0,a.length - 1);
System.out.println("最終排序結果"+Arrays.toString(a));
}
運行結果如下圖:
4.C代碼實現
void quickSort(int arr[], int left, int right) {
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
/* partition */
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
/* recursion */
if (left < j)
quickSort(arr, left, j);
if (i < right)
quickSort(arr, i, right);
}
5.快速排序的性能分析.
a.最壞情況分析
在最壞情況下,快速排序每一層遞歸的時間複雜度是n的平方.
特例:當劃分非平衡的時候,快速排序的運行時間爲n的平方
b.期望運行時間
在輸入元素互異的情況下,快速排序算法的期望運行時間爲n lg n.
如有疑問請直接在評論提出
不足之處請指正,謝謝!