(本博客旨在个人总结回顾)
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;
}
运行结果:
注意:
在递归太深的情况下会导致栈溢出,原因是因为系统栈空间有限,当递归函数中一般需要用到局部变量,局部变量存在栈中,所以在递归太深的情况下就会导致栈溢出。
当然在上面的例子中,只要组数足够大,你总能体验栈溢出的提示,上面的例子,数组空间也是在栈中的。