快速排序

快速排序是冒泡排序的改進版,也是最好的一種內排序,在很多面試題中都會出現,也是作爲程序員必須掌握的一種排序方法。

算法思想:

1.在待排序的元素任取一個元素作爲基準(通常選第一個元素)稱爲基準元素;

2.將待排序的元素進行分區,比基準元素大的元素放在它的右邊,比其小的放在它的左邊;

 3.對於基準元素左邊的元素進行上述步驟的遞歸調用進行排序,基準元素右邊的元素也是如此。

你可以把快速排序聯想成東拆西補或西拆東補,一邊拆一邊補,直到所有元素達到有序狀態。

看看下圖來理解一下快速排序的思想

以上相當於一趟的排序,然後對基準左邊的元素和右邊的元素重複上述步驟進行遞歸就可以了。

快速排序實現代碼如下:

#include<stdio.h>

void quickSort(int arr[],int _left,int _right){
	if(_left<_right){				//待排元素至少需要兩個纔會進入if 
		int temp=arr[_left];      	//定義基準元素 
		int left=_left;				
		int right=_right;
		while(left<right){			//從左右兩邊交替掃描,直到left=right
			while(left<right&&arr[right]>temp){
				right--;		//從右往左掃描,尋找比基準元素小的元素
			}
			arr[left]=arr[right];	//找到這種元素arr[right]後與arr[left]交換
			while(left<right&&arr[left]<temp){
				left++;			//從左往右掃描,尋找比基準元素大的元素
			}
			arr[right]=arr[left];	//找到這種元素arr[left]後,與arr[right]交換
		}
		arr[left]=temp;				//基準元素放到arr[left]位置上 
		quickSort(arr,_left,left-1);   	//對基準元素左邊元素遞歸排序 
		quickSort(arr,left+1,_right);	//對基準元素右邊元素遞歸排序 
	}
}



int main(void){
	int arr[7]={3,2,5,8,4,7,6};
	quickSort(arr,0,6);
	for(int i=0;i<7;i++){
		printf("%3d",arr[i]);
	} 
}

接下來我們來討論快速排序的最優情況和最差情況:

最優情況:最優情況就是數組每次劃分都很均勻,例如如果排序n個關鍵字,其遞歸樹的深度就爲 [log2n]+1( [x] 表示不大於 x 的最大整數),即僅需遞歸 log2n 次。而每一次排序需要遍歷一次當前排序的數組,因此最優情況下,快速排序的時間複雜爲O(nlog2n)

最壞情況:最壞情況就是當待排序的序列爲正序或逆序排列時,且每次劃分只得到一個比上一次劃分少一個記錄的子序列,注意另一個爲空。如果遞歸樹畫出來,它就是一棵斜樹。此時需要執行n‐1次遞歸調用,且第i次劃分需要經過n‐i次關鍵字的比較才能找到第i個記錄,也就是樞軸的位置,因此比較次數爲,最終其時間複雜度爲O(n^2)。

總結:快速排序時間複雜度爲,空間複雜度爲,是一種不穩定的交換排序。