(本博客旨在個人總結回顧)
1.概括
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
2.實現
C++遞歸和非遞歸實現:(一般遞歸轉爲非遞歸,可以使用stack實現)
// quickSort.cpp : 定義控制檯應用程序的入口點。
//
//個人博客:https://blog.csdn.net/qq_23903863
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <stack>
using namespace std;
/*
* @name PartSort
* @brief 以第一個數組元素爲基準
大於等於該基準的值放置組數右側
小於該基準的值放置數組左側
最後該基準放置於中間位置
* @param [in] int * pArray 待排序數組
* @param [in] int nLeft 最左側下標
* @param [in] int nRight 最右側下標
* @return int 中間位置下標
*/
int PartSort(int* pArray, int nLeft, int nRight)
{
int nKey = pArray[nLeft];
while (nLeft < nRight)
{
while (pArray[nRight] >= nKey && nRight > nLeft)
{
nRight--;
}
pArray[nLeft] = pArray[nRight];
while (pArray[nLeft] < nKey && nLeft < nRight)
{
nLeft++;
}
pArray[nRight] = pArray[nLeft];
}
pArray[nLeft] = nKey;
return nLeft;
}
/*
* @name QuickSortRecursion
* @brief 快速排序遞歸實現
* @param [in] int * pArray 待排序的數組
* @param [in] int nLeft 數組左下標
* @param [in] int nRight 數組右下標
* @return void
*/
void QuickSortRecursion(int* pArray, int nLeft, int nRight)
{
if (NULL == pArray)
{
return;
}
if (nLeft >= nRight)
{
return;
}
int nMid = PartSort(pArray, nLeft, nRight);
QuickSortRecursion(pArray, nLeft, nMid - 1);
QuickSortRecursion(pArray, nMid + 1, nRight);
}
/*
* @name QuickSortUnrecursion
* @brief 快速排序非遞歸實現
* @param [in] int * pArray 待排序數組
* @param [in] int nLeft 起始下表
* @param [in] int nRight 終止下表
* @return void
*/
void QuickSortUnrecursion(int* pArray, int nLeft, int nRight)
{
if (NULL == pArray && nLeft >= nRight)
{
return;
}
stack<int> stackIndex;
stackIndex.push(nLeft);
stackIndex.push(nRight);
int nBegin = 0;
int nEnd = 0;
int nMid = 0;
while (!stackIndex.empty())
{
nEnd = stackIndex.top();
stackIndex.pop();
nBegin = stackIndex.top();
stackIndex.pop();
nMid = PartSort(pArray, nBegin, nEnd);
if (nBegin < nMid - 1)
{
stackIndex.push(nBegin);
stackIndex.push(nMid - 1);
}
if (nEnd > nMid + 1)
{
stackIndex.push(nMid + 1);
stackIndex.push(nEnd);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
//測試例子
//①空指針;
//②1個元素;
//③2個元素;
//④3個元素;
//⑤100個元素;
//⑥100萬個元素 在本人(vs2013)默認開發環境下,(遞歸)4000個元素髮生棧溢出 (非遞歸)300000個元素髮生棧溢出
int array1[15] = {};//修改數組大小就可改變元素個數,實現升序排序測試
int nLength = sizeof(array1) / sizeof(array1[0]);
int nUn = -1;
srand(time(0));
for (int i = 0; i < nLength; i++)
{
nUn *= -1;
array1[i] = rand() * nUn;
}
cout << "排序前:" << endl;
for (int i = 0; i < nLength; i++)
{
cout << array1[i] << " ";
}
QuickSortUnrecursion(array1, 0, nLength - 1);
cout << endl << "排序後" << endl;
for (int i = 0; i < nLength; i++)
{
cout << array1[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
運行結果:
注意:
在遞歸太深的情況下會導致棧溢出,原因是因爲系統棧空間有限,當遞歸函數中一般需要用到局部變量,局部變量存在棧中,所以在遞歸太深的情況下就會導致棧溢出。
當然在上面的例子中,只要組數足夠大,你總能體驗棧溢出的提示,上面的例子,數組空間也是在棧中的。