前言:
为什么要实现快排非递归算法,不是已经有了递归算法了吗?
计算机在实现递归时会调用系统的堆栈,这很消耗计算机内存资源,所以采用非递归算法的本质就是手动模拟系统的堆栈调用来降低computer资源的消耗。
快排的详细讲解和递归算法的入口:https://blog.csdn.net/y_16041527/article/details/80460015
话不多讲,直接看代码(有注释)
#include <iostream>
#include <stack>
using namespace std;
//划分算法
int Partition( int a[], int low, int high )
{
//假设每次都以第一个元素作为枢轴值,进行一趟划分:
int pivot = a[low];
while( low<high )
{
while( low<high && a[high]>=pivot )
--high;
a[low] = a[high]; //停下来做交换
while( low<high && a[low]<=pivot )
++low;
a[high] = a[low]; //停下来做交换
}
a[low] = pivot; //pivot的最终落点
return low;
}
//非递归快排
void QuickSort(int a[], int left, int right)
{
//手动利用栈来存储每次分块快排的起始点
//栈非空时循环获取中轴入栈
stack<int> s;
if( left<right )
{
int boundary = Partition(a,left,right);
if( boundary-1>left ) //确保左分区存在
{
//将左分区端点入栈
s.push(left);
s.push(boundary-1);
}
if( boundary+1<right ) //确保右分区存在
{
s.push(boundary+1);
s.push(right);
}
while( !s.empty() )
{
//得到某分区的左右边界
int r = s.top();
s.pop();
int l = s.top();
s.pop();
boundary = Partition(a,l,r);
if( boundary-1>l ) //确保左分区存在
{
//将左分区端点入栈
s.push(l);
s.push(boundary-1);
}
if( boundary+1<r ) //确保右分区存在
{
s.push(boundary+1);
s.push(r);
}
}
}
}
int main()
{
int a[5] = { 4, 1, 5, 3, 2 };
int left = 0, right = 4;
QuickSort(a,left,right);
//输出,检验结果
for( int i=0; i<5; ++i )
{
cout << a[i] << " ";
}
cout << endl;
}