快速排序html
算法思想:基於分治的思想,是冒泡排序的改進型。首先在數組中選擇一個基準點(該基準點的選取可能影響快速排序的效率,後面講解選取的方法),而後分別從數組的兩端掃描數組,設兩個指示標誌(lo指向起始位置,hi指向末尾),首先從後半部分開始,若是發現有元素比該基準點的值小,就交換lo和hi位置的值,而後從前半部分開始掃秒,發現有元素大於基準點的值,就交換lo和hi位置的值,如此往復循環,直到lo>=hi,而後把基準點的值放到hi這個位置。一次排序就完成了。之後採用遞歸的方式分別對前半部分和後半部分排序,當前半部分和後半部分均有序時該數組就天然有序了。java
排序過程:算法
算法實現:數組
public static int partition(int []array,int lo,int hi){ //固定的切分方式 int key=array[lo]; while(lo<hi){ while(array[hi]>=key&&hi>lo){//從後半部分向前掃描 hi--; } array[lo]=array[hi]; while(array[lo]<=key&&hi>lo){從前半部分向後掃描 lo++; } array[hi]=array[lo]; } array[hi]=key; return hi; } public static void sort(int[] array,int lo ,int hi){ if(lo>=hi){ return ; } int index=partition(array,lo,hi); sort(array,lo,index-1); sort(array,index+1,hi); }
快速排序的時間複雜度爲O(NlogN).post
快速排序的優化優化
對於基準位置的選取通常有三種方法:固定切分,隨機切分和三取樣切分。固定切分的效率並非太好,隨機切分是經常使用的一種切分,效率比較高,最壞狀況下時間複雜度有可能爲O(N2).對於三數取中選擇基準點是最理想的一種。ui
三數取中切分:url
public static int partition(int []array,int lo,int hi){ //三數取中 int mid=lo+(hi-lo)/2; if(array[mid]>array[hi]){ swap(array[mid],array[hi]); } if(array[lo]>array[hi]){ swap(array[lo],array[hi]); } if(array[mid]>array[lo]){ swap(array[mid],array[lo]); } int key=array[lo]; while(lo<hi){ while(array[hi]>=key&&hi>lo){ hi--; } array[lo]=array[hi]; while(array[lo]<=key&&hi>lo){ lo++; } array[hi]=array[lo]; } array[hi]=key; return hi; } public static void swap(int a,int b){ int temp=a; a=b; b=temp; } public static void sort(int[] array,int lo ,int hi){ if(lo>=hi){ return ; } int index=partition(array,lo,hi); sort(array,lo,index-1); sort(array,index+1,hi); }
快速排序在序列中元素不多時,效率將比較低,否則插入排序,所以通常在序列中元素不多時使用插入排序,這樣能夠提升總體效率。spa
public static void quick(int []array ,int lo,int hi){ if(hi-lo+1<10){ insertSort(array); }else{ quickSort(array,lo,hi); } }