快速排序的核心操做就是劃分,在(java數據結構與算法)中也單獨將劃分劈出一個章節來講,如今你們應該已經知道經過設置兩個指針分別從數組的左右兩側向中間進行掃描的方式來實現劃分操做(此方法就是排序––快速排序(二)中給出的一個初步劃分方案,而且那是在特殊序列並選擇了特殊軸樞元素狀況下才容易讓人理解),當隨機選擇一個不能將整個序列平均劃分的時候我的認爲該方法不太好理解,現按照本身的理解來寫一個正確的快速排序代碼,並嘗試用該方法過分到通用方法中(這裏要感謝我同事給個人幫助,由於根據他給的初步方法纔有了下面的內容),該篇先寫一個正確的劃分代碼。java
一、假如讓咱們本身來實現一個劃分算法,首先會從已知序列中選擇一個元素做爲軸樞(注意該選擇是隨機的,咱們的重點先放在如何寫一個正確的劃分算法上面)。算法
二、從序列的左邊開始掃描(設指針變量爲i),若是遇到一個小於等於軸樞元素的數就直接跳過進行下個元素的比較;若是遇到一個大於軸樞的元素就要從下一個元素(設指針變量爲j初始值爲i+1)開始尋找一個小於等於軸樞的元素並與該元素交換。數組
三、當變量j到達序列的末尾時說明再也沒有小於等於軸樞的元素了表示劃分結束或者當變量i到達序列的末尾時說明序列全部的元素都小於等於軸樞元素,因此變量i的本質是左右序列的邊界位置(邊界位置的元素永遠大於軸樞或者因爲超過了序列的長度而不存在,或者換個說法i-1位置的元素小於等於軸樞元素),而變量j的本質是用來尋找小於等於軸樞元素的。當劃分結束的時候還要將軸樞元素與i-1位置上的元素進行交換!這裏假設序列共有元素n個,第一趟排序實際比較次數爲n次。這與一般的劃分算法(經過左右兩邊向中間掃描)比較次數同樣,只是這裏是由左向右的掃描方法,我的認爲這種方式更好理解,代碼以下:數據結構
public int partition(int from, int to) {
int partPos = from;
int ltePos = from + 1;
int pivotPos = -1;
while (true) {
int comp = 0;
while (partPos <= to && (comp = comparePivot(partPos)) <= 0) {
if (comp == 0) {
pivotPos = partPos;
}
partPos++;
}.net
if (partPos > ltePos) {
ltePos = partPos + 1;指針
}
while (ltePos <= to && comparePivot(ltePos) > 0) {
ltePos++;
}
if (partPos > to || ltePos > to) {
break;
}
swap(partPos, ltePos);
}
int actPartPos = partPos - 1;
swap(pivotPos, actPartPos);
return actPartPos;
}blog