快速排序(C++实现、递归、非递归)

(本博客旨在个人总结回顾)

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;
}

运行结果:

注意:

在递归太深的情况下会导致栈溢出,原因是因为系统栈空间有限,当递归函数中一般需要用到局部变量,局部变量存在栈中,所以在递归太深的情况下就会导致栈溢出。

当然在上面的例子中,只要组数足够大,你总能体验栈溢出的提示,上面的例子,数组空间也是在栈中的。

 

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