圖解快速排序
前言
快速排序是應用相當廣泛的排序演算法,在Java的java.util.Arrays這個類裡面的sort()方法就是使用的快速排序,其內部是呼叫了一個類的靜態方法DualPivotQuicksort.sort(),此類實現了Vladimir Yaroslavskiy,Jon Bentley和Josh Bloch的Dual-Pivot Quicksort演算法。 該演算法可在許多資料集上提供O(n log(n))效能,這會導致其他快速排序降級為二次效能,並且通常比傳統的(單軸)Quicksort實現要快。 所有公開的方法都是程式包專用的,旨在在執行任何必要的陣列邊界檢查並將引數擴充套件為所需形式之後從公共方法(在Arrays類中)呼叫.在面試中,也經常要求面試者能手撕快速排序。接下來我們就對快排來一探究竟。快速排序是什麼?
- 快速排序演算法是一種分治的排序演算法,是對氣泡排序的一種改進演算法,快速排序的實現核心思想就是對原始陣列進行分而治之,遞迴呼叫,從而實現對陣列的排序,並且時間複雜度與NlogN 成正比。
圖解快速排序
- 以陣列[7,11,4,3,8,10,2,13,5,14]為例子,一步一步的圖解刨析快速排序。
- 快速排序的第一步是找到一個基準數,將陣列以這個基準數,分為兩部分,右邊的是小於基準數的,左邊的是大於基準數的。為了方便處理,我們都是以陣列第一個元素作為基準數的。 此時基準數為temp=7.
第一輪,
① right向左移動,執行right–運算,直到arr[right]小於基準數temp=6時,就暫停移動;left向右移動,執行left++運算,直到arr[left]>temp時,停止移動,然後交換arr[right]和arr[left]的值。
- ② 重複第一步
- ③ 比較關鍵的一步來了,此時right繼續左走,走到arr[right]=2時,發現是小於基準數6,這時候停止移動。最最關鍵的來了,那麼此時left還需要繼續走嗎? 答案 是否的。 因為此時left已經和right相遇了,這是終止每一輪的條件,即left<right.
- ④ 我們經過第一輪的左右指標移動,比較並交換左右指標的值,這一系列的最終目的就是使得我們的陣列 被分割為兩部分:基準數左邊的數小於 它,而右邊的數要大於它。 那麼緊接著就 將arr[left]與基準數進行交換,就達到了我們的目的。
- 如此一來,經過第一輪的遍歷交換,我們就將 陣列 基準數的右邊 都小於了它, 左邊都大於它。
第二輪
接下來幹嘛??我們經過第一輪的操作,達成了我們的初步目標,要實現全面排序,後面還得繼續重複第一輪的操作,直到整個陣列完全有序為至。如何重複呢? 我們先從第一輪基準數的右邊開始,分割出陣列[2,5,4,3],重複第一輪的操作。此時的基準數temp=2.
- ① right 向左移動,直到 遇到 小於等於基準數的值時停止左邊移動。left準備右移動時,已經left==right了 已經滿足 基準數的左邊 大於右邊的要求了,那麼就自我交換一次。並從基準數的右邊開啟第三輪的操作。
第三輪
- 依舊重複 第一輪的操作。
- ① 初始時right所在的元素已經小於的基準數temp=5了,那麼直接不移動,然後left開始右移動,沿途沒有發現大於基準的元素,因此直到left==right時,停止移動。 並將arr[left]與基準數temp進行交換。
此時 已 temp=7為基準數的陣列的右邊已經完全有序了,那麼繼續對基準數左邊的陣列重複第一輪即可得到完整的排序陣列。
總結
- 從整個流程可以發現,快速排序的比較和交換次數比氣泡排序少很多,並且也很少移動元素,這是快速排序比其他排序快的重要因素。但並不意味著,這是最優的快速排序演算法。快速排序的應用實際上還要看具體場景,對於小陣列的排序,當陣列元素小於47時,優先選擇插入排序進行排序。如果要排序的是位元組陣列的長度大於29,則優先使用計數排序而不是插入排序.如果要排序的short或char陣列的長度大於3200,則優先使用計數排序而不是Quicksort.
- 最後附上 程式碼 僅供參考
void quieckSort(int [] arr,int start,int end){
if(start>end)
return;
//以第一個元素作為基準數
int temp=arr[start];
int left=start;
int right=end;
while(left<right){
//在右邊找到小於基準數的值
while(left<right&&arr[right]>=temp){
right--;
}
//在左邊找到大於基準數的值
while(left<right&&arr[left]<=temp){
left++;
}
//交換這兩個值
if(right>left){
int t=arr[left];
arr[left]=arr[right];
arr[right]=t;
}
}
//基準數的交換
arr[start]=arr[left];
arr[left]=temp;
//遞迴 對 基準數 的左右兩邊繼續快排
quickSort(arr,start,left-1);
quickSort(arr,left+1,end);
}
- 如果對你有幫助 就點一個贊吧。嘻嘻。
相關文章
- 演算法圖解之快速排序演算法圖解排序
- 【演算法】演算法圖解筆記_快速排序演算法圖解筆記排序
- 8行程式碼實現快速排序,簡單易懂圖解!行程排序圖解
- JavaScript快速排序功能詳解JavaScript排序
- 演算法 | 快速排序詳解演算法排序
- O(nlogn)快速排序-雙路排序+詳細註解排序
- 排序之快速排序排序
- 資料結構與演算法 排序演算法 快速排序【詳細步驟圖解】資料結構演算法排序圖解
- 排序:氣泡排序&快速排序排序
- 圖解選擇排序與插入排序圖解排序
- 快速排序排序
- 快速排序&&歸併排序排序
- 圖解排序演算法圖解排序演算法
- 快速排序快速入門排序
- 分治思想--快速排序解決TopK問題排序TopK
- 排序演算法__快速排序排序演算法
- 排序演算法:快速排序排序演算法
- 選擇排序和快速排序排序
- 四、歸併排序 && 快速排序排序
- 排序演算法 - 快速排序排序演算法
- javascript 快速排序JavaScript排序
- 快速排序javaScript排序JavaScript
- js 快速排序JS排序
- 快速排序-java排序Java
- LeetCode:快速排序LeetCode排序
- 快速排序法排序
- 分治—快速排序排序
- java 快速排序Java排序
- python 快速排序Python排序
- 圖解JavaScript演算法排序圖解JavaScript演算法排序
- 圖解堆排序演算法圖解排序演算法
- php插入排序,快速排序,歸併排序,堆排序PHP排序
- 排序演算法之 '快速排序'排序演算法
- 遞迴-*快速排序遞迴排序
- 快速排序 (Quick Sort)排序UI
- 快速排序C++排序C++
- 三種快速排序排序
- 8.22_快速排序排序