目錄
一、概述
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲較小和較大的2個子序列,然後遞歸地排序兩個子序列。
步驟爲:
- 挑選基準值:從數列中挑出一個元素,稱爲“基準”(pivot),
- 分割:重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(與基準值相等的數可以到任何一邊)。在這個分割結束之後,對基準值的排序就已經完成,
- 遞歸排序子序列:遞歸地將小於基準值元素的子序列和大於基準值元素的子序列排序。
遞歸到最底部的判斷條件是數列的大小是零或一,此時該數列顯然已經有序。
選取基準值有數種具體方法,此選取方法對排序的時間性能有決定性影響。
二、快速排序實現
1、雙指針法實現分割數組
這個雙指針法實現分割數組可以解決很多問題,其中有個移0問題(把數組中所有的0都移到後面)也可以用這個方法解決。
int partionArray(std::vector<int> &vecNums, int left, int right,int pvIndex)
{
int pvval = vecNums[pvIndex];//保存基準值
std::swap(vecNums[pvIndex], vecNums[right]);//基準值換到最後
int storeIndex = left;//指向最後一個滿足<= pvval索引的下一個位置,雙指針中一個指針
for (int i = left; i < right; ++i)//i爲雙指針的第二個指針
{
if (vecNums[i] <= pvval)
{
std::swap(vecNums[i], vecNums[storeIndex]);
storeIndex++;
}
}
std::swap(vecNums[storeIndex], vecNums[right]);
return storeIndex;
}
2、quicksort實現
有了這個partionArray,quicksort就比較容易寫出來了。
void quicksort(std::vector<int> &vecNums, int left, int right)
{
if (right > left)
{
int pvIndex = rand()%(right-left+1) +left;//隨機選擇基準值
int parIndex = partionArray(vecNums, left, right, pvIndex);
quicksort(vecNums, left, parIndex - 1);
quicksort(vecNums, parIndex + 1, right);
}
}
3、quick sort調用
int main()
{
std::vector<int> vecNums = { 2,4,9,1 };
quicksort(vecNums, 0, vecNums.size() - 1);
return 0;
}
三、總結
這裏的關鍵是partionArray的雙指針方法,大家可以重點掌握,這個方法可以用來解決一系列的問題。