畢業到如今也差很少一年了,以前在校搞ACM時候的痛苦經歷已經不在,踏入工做到如今,算法思惟逐漸的丟失,工做中遇到的問題也涉及暫時涉及不到算法,記得最後一次用到算法也就是畢設時候了,當時用unity3d寫了一個rpg遊戲,尋路算法採用的是A*。如今嗎....能想起A*的原理已經不錯了,因此打算今天開始重新拾回個人算法思惟,先從快速排序開始吧,排序也算是最基礎的算法了,工做中也是常常使用到(用庫函數的就不說了);算法
先來講說快速排序的原理吧,數組
我本身常常吧快排稱之爲左右挖坑填坑算法......額,好吧,黃色那部份內容呢,是百度上的,其中有我認爲不許確的地方,如第3)4)最後的互換兩字我以爲用的不恰當,或者說錯誤。應該改成將A[j]的值賦值給A[i],而此時咱們並不須要理會A[j],也就是a[j]將是做爲下一個「坑」,「左右挖坑填坑」就是這麼來的。爲何這麼說呢,且看我用一個來分析。函數
(以升序爲例,倒敘也就是改下符號而已)假設有一個待排序的數組[35,5,42,78,13,29],那麼它的第一趟執行完以後是怎樣得呢?ui
好了,理論分析部分完成了,下面一步一步分析代碼實現快排的過程。spa
假設代碼只執行了第一步和第二部,代碼:3d
1 public static void quickSort(int[] arr, int left, int right) { 2 int key = arr[left]; 3 int i = left; 4 int j = right; 5 while (i < j && arr[j] >= key) { //從右向左找比key小的值 6 j--; 7 } 8 arr[i] = arr[j];//arr[j]比key小,填入第一個坑 9 while (i < j && arr[i] <= key) { //從左向右找比key大的值 10 i++; 11 } 12 arr[j] = arr[i];//arr[i]>key ,填入上一個坑 13 }
若是要將一整輪都走完,代碼:指針
1 public static void quickSort(int[] arr, int left, int right) { 2 int key = arr[left]; 3 int i = left; 4 int j = right; 5 while (i < j) {//若是i不等於j,那麼就繼續左右挖坑填坑 6 while (i < j && arr[j] >= key) { //從右向左找比key小的值 7 j--; 8 } 9 arr[i] = arr[j];//arr[j]比key小,填入第一個坑 10 while (i < j && arr[i] <= key) { //從左向右找比key大的值 11 i++; 12 } 13 arr[j] = arr[i];//arr[i]>key ,填入上一個坑 14 } 15 arr[i] = key;//當i==j,將key的值填入這一輪比較的最後一個坑中 16 }
接下來就簡單了,快排整個函數完成 代碼:code
1 public static void quickSort(int[] arr, int left, int right) { 2 if (left < right) {//終止遞歸的條件。 3 int key = arr[left]; 4 int i = left; 5 int j = right; 6 while (i < j) {//若是i不等於j,那麼就繼續左右挖坑填坑 7 while (i < j && arr[j] >= key) { //從右向左找比key小的值 8 j--; 9 } 10 arr[i] = arr[j];//arr[j]比key小,填入第一個坑 11 while (i < j && arr[i] <= key) { //從左向右找比key大的值 12 i++; 13 } 14 arr[j] = arr[i];//arr[i]>key ,填入上一個坑 15 } 16 arr[i] = key;//當i==j,將key的值填入這一輪比較的最後一個坑中 17 quickSort(arr, left, i - 1);//左邊部分執行一輪步驟 18 quickSort(arr, i + 1, right);//右邊部分執行一輪步驟 19 } 20 }
快排完成,其中值得注意的是:有些人會將 第7行 arr[j]>=key 條件和第11行 arr[i]<=key條件寫成 arr[j]>key和 arr[i]<key 。表面上看好像也是正確的,但當有兩個數字同樣的時候,htm
6 while (i < j) {//若是i不等於j,那麼就繼續左右挖坑填坑
7 while (i < j && arr[j] >= key) { //從右向左找比key小的值
8 j--;
9 } 10 arr[i] = arr[j];//arr[j]比key小,填入第一個坑 11 while (i < j && arr[i] <= key) { //從左向右找比key大的值 12 i++; 13 } 14 arr[j] = arr[i];//arr[i]>key ,填入上一個坑 15 }
這段代碼會出現死循環,至於爲何會死循環,請將我上面的步驟一步一步推演,便可得知。