快速排序是實踐中已知的最快的排序演算法,平均執行時間o(nlogn),該演算法之所以快是因為非常精煉和高度優化的內部迴圈。它也是一種分治的遞迴演算法,將陣列s排序的基本演算法由下列簡單的四步組成:
如果s中元素個數是0或1,則返回。
取s中任一元素v,稱之為樞紐元。
將s-分成兩個不相交的集合s1=|x<=v}和s2=|x>=v}
返回quicksort(s1)後,繼隨v,繼而quicksort(s2)。
對於那些樞紐元的元素的處理,第三步分割的描述不是唯一的,因此這就成了乙個設計上的決策,一部分好的實現方法是將這種情形盡可能有效的處理。下**釋了快排對乙個數集的操作。
快速排序比歸併更快的原因在於第三步分割成兩組在適當的位置進行並且非常有效,它的高效彌補甚至超出了大小不等的遞迴呼叫。
選取樞紐元一種錯誤的方法
通常沒有充分考慮的選擇是將第乙個元素作為樞紐元(或者選取前兩個互異關鍵字中較大者作為樞紐元),如果輸入是預先排好序的或者反序的,因為所有的元素都不是s1,都被劃入s2,此外第乙個元素做樞紐元並且輸入預先排好序,快排花費的時間將是二次的。
一種安全的做法
安全的做法是隨機選取樞紐元,但代價昂貴,根本減少不了演算法其餘部分的平均執行時間。
最好的選擇
三數中值分割法,一組n個數的中值是第n/2個最大的數,樞紐元最好的選擇是陣列的中值,一般做法是使用左端、右端、中心位置三個元素樞紐值作為樞紐元。
分割策略
有幾種分割策略用於實踐,但此處描述的分割方法能夠給出好的結果,該法的第一步是通過將樞紐元與最後的元素交換使得樞紐元要離開被分割的資料段,i從第乙個元素開始而j從倒數第二個元素開始。
分割階段要做的就是把所有小元素移到陣列的左邊而把所有的大元素移到陣列的右邊。大小相對於樞紐元素而言。
當i在j的左邊時,將i右移,移過那些小於樞紐元的元素;並將j右移,移過那些大於樞紐元的元素,當i和j停止時,i指向乙個大元素而j指向乙個小元素,如果i在j的左邊,那麼這兩個元素互換一下,其效果是把乙個大元素移向右邊而把小元素移向左邊,下面為交換過程:
交換i和j指向的元素直到i和j彼此交錯為止。
分割最後一步是將樞紐元與i指向元素交換。
在最後一步當樞紐元與i所指向的元素交換時,我們知道在位置pi上的元素都是大元素。
必須考慮的重要細節是如何處理等於樞紐元的關鍵字,先考慮陣列中所有關鍵字都相等的情況,如果i和j都停止,在相等的元素間將會有多次交換,其正面意義是i和j在中間交錯,分割建立了兩個相等的子陣列,因此總的執行時間是o(nlogn)。而如果i和j都不停止或者其中乙個停止都會花費o(n2)的時間,因此讓i,j停止效率更高。
對於很小的陣列(n<=20)快排不如插入排序好,通常解決辦法是對於小的陣列不遞迴地使用快速排序,而採用插入排序。
實際的快排例程:
在這裡插入**片
經典排序演算法 快速排序
使用分割槽演算法並找出主元 對主元兩邊的序列分別進行排序 整體時間複雜度 o nlog n public class quicksort 分割槽演算法 public static intpartition int a,int l,int r else if a l a mid a l a r els...
經典演算法 快速排序
題目說明 快速排序是由東尼 霍爾所發展的一種排序演算法。在平均狀況下,排序n 個專案要 n log n 次比較。在最壞狀況下則需要 n2 次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他 n log n 演算法更快,因為它的內部迴圈 inner loop 可以在大部分的架構上很有效率地被實...
經典排序演算法 氣泡排序 快速排序
氣泡排序的基本思想是,對相鄰的元素進行兩兩比較,順序相反則進行交換,這樣,每一趟會將最小或最大的元素 浮 到頂端,最終達到完全有序。特點 如果n個元素按照從小到大排序,每一輪 i 排序後,最大的元素會放到最後,後續新一輪只需要前n i個元素互相比較。題目 給出無需陣列 4,3,1,2 要求按照從小到...