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,
这样一个序列已经划分为两个子序列,对每个子序列按上述递归得到在原位置排序好的序列。
如果将判断依据作为参数传入快排方法,就会灵活很多。