指標交換法的快速排序不會實現怎麼辦?
阿新 • • 發佈:2018-12-20
我們先來了解一下什麼是指標交換法的快速排序。
在一個數組裡任意選擇一個數作為支點,方便起見選取第一個數為支點。把所有比支點小的數都放在支點的左側,而所有比支點大的數都放在支點的右側,這樣一個數組就分成了三個部分:
【比支點小的部分】 | 【支點】 | 【比支點大的部分】 |
---|
然後我們繼續對支點兩邊凌亂的陣列呼叫該方法,直到陣列只有一個數,即支點兩側無數為止。
你可能會說,我知道這樣可我還是不會敲程式碼
別急咱一步一步慢慢來,我們先分析單次的執行
- 定義一個支點pivot儲存著第一個元素的值
- 定義一個索引i指向第一個數往後遍歷找到比支點大的值
- 定義一個索引j指向最後一個數往前遍歷找到比支點小的值
- 重複步驟2 3,直到i,j相遇
圖示如下:
i開始找比pivot大的數,就開始找比pivot小的數,找到後交換兩數
下來就出了一點問題,我們是先移動i呢,還是先移動j呢。其實很簡單因為最後要使pivot與arr[i]進行交換所以那就移動j,i保持不動。之後我們就得到了如下結果 這個例子可能對先移動誰不夠鮮明,我們試想一下下面這種情況。 升序排列的陣列j連一次移動的機會都沒有,便會得到如下結果: 然後1跟6再交換一下emmm很顯然做不到pivot的左邊比pivot小 圖也嗶嗶了半天了,上程式碼吧
public static void quickSort(int[] arr,int left,int right){ int i = left;//向右索引 int j = right;//向左索引 int temp; if(right<left){return;} int pivot = arr[left];//選取第一個數為支點 while(i<j){ while(i<j&&arr[j]>=pivot){//獲取比支點小的元素下標 j--; } while(i<j&&arr[i]<=pivot){//獲取比支點大的元素下標 i++; } //把兩個數交換 temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } arr[left] = arr[i]; arr[i] = pivot; //現在陣列被分為了三個部分 // 【比支點小的部分】【支點arr[i]】【比支點大的部分】 quickSort(arr,left,i-1);//分別對兩側進行同樣操作即可 quickSort(arr,i+1,right); } }
然後我們發現這個引數實在好長啊,我們要給arr排序還得這麼寫 quickSort(arr,0,arr.length-1)。這種重複的無意義的工作就交給計算機去做吧,程式設計師該做的就應該是偷懶。我們把它再封裝到一個方法裡。
public static void quickSort(int arr[]){
quickSort(arr,0,arr.length-1);
}
這樣看起來是不是就清爽了很多~