public delegate bool CompareDelegate(HPoint2d point0, HPoint2d point1);
public void QuikSort(List<HPoint2d> lstPoint, int indexS, int indexE, CompareDelegate
compare)
{
if (indexE <= indexS)
return;
int indexP = Partition(lstPoint, indexS, indexE, compare);
QuikSort(lstPoint, indexS, indexP - 1, compare);
QuikSort(lstPoint, indexP + 1, indexE, compare);
}
public int Partition(List<HPoint2d> lstPoint, int indexS, int indexE, CompareDelegate
compare)
{
HPoint2d ptBase = lstPoint[indexE];
int i = indexS - 1;
for(int j = indexS; j < indexE; j++)
{
if(compare(lstPoint[j], ptBase))
{
i++;
var ptTemp = lstPoint[i];
lstPoint[i] = lstPoint[j];
lstPoint[j] = ptTemp;
}
}
var ptTemp2 = lstPoint[i + 1];
lstPoint[i + 1] = lstPoint[indexE];
lstPoint[indexE] = ptTemp2;
return i + 1;
}
(1)對於一個序列,首先將各元素與最後一個元素進行比較,並將較小的元素放到其左邊,較大元素放到其右邊;
(2)得到兩個子序列,對每個子序列按上述方法處理,遞歸處理;
(3)即得到原位置已排序號的序列。
關鍵位置在Partition方法,該方法運用了歸納法,
1)初始條件:int i = indexS - 1;int j = indexS;
i及其前的所有元素都小於最後一個元素ptBase;i與j之間([i,j))的所有元素都大於ptBase;
2)若j<ptBase,說明比ptBase小的元素增加1,即i++,並將i與j元素互換;----情況1
若j>ptBase,不作處理;----情況2
然後j++進行下一次判斷。
注意i與j元素互換的一步是爲了處理當出現情況2後再次出現情況1時,比ptBase小的元素應該+1(i++),爲了保證處理後仍然滿足i及其前的所有元素都小於最後一個元素ptBase;i與j之間([i,j))的所有元素都大於ptBase需將i位置元素(大於ptBase)與j位置元素(小於ptBase)互換。
3)經過第二步處理後,依然滿足i及其前的所有元素都小於最後一個元素ptBase;i與j之間([i,j))的所有元素都大於ptBase這一條件;
4)循環第二步直到j==indexEnd-1;每次處理後都滿足上述紅色字體所注條件;
結束循環時,對於該序列,i及其前的所有元素都小於最後一個元素ptBase;i與j之間([i,j))的所有元素都大於ptBase,此時只需要將i+1位置元素(大於ptBase)與ptBase位置互換後就滿足該序列ptBase(i+1位置)之前的所有元素小於等於ptBase,之後的所有元素大於ptBase,
這樣一個序列已經劃分爲兩個子序列,對每個子序列按上述遞歸得到在原位置排序好的序列。
如果將判斷依據作爲參數傳入快排方法,就會靈活很多。