【快速排序】快速排序與數學歸納法

      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,

這樣一個序列已經劃分爲兩個子序列,對每個子序列按上述遞歸得到在原位置排序好的序列。

如果將判斷依據作爲參數傳入快排方法,就會靈活很多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章