递归和栈溢出。
递归确实是很多算法的基础思想。但外部因素导致递归会栈溢出。
但却是不甘心如此简练的有效的算法,放弃不用。
所以一般有2中方式来使用大数据的递归思路
1)用栈类型放入参数,模拟递归调用。
2)把大数据分割为一批适中的数据,就可以直接使用递归函数。
用快速排序,测试并总结了下。
1)本例大概 排序30000个数字,递归就溢出。
2)用局部变量的栈类型。也不超过90000个数字。 不知道为什么,看来要看下stack的实现。
3)栈类型用指针,放入堆中。到此问题解决。
#include <iostream>
#include <stack>
using namespace std;
void quickS(int* left,int* right);
void quickS2(int* left,int* right);
int main()
{
int intArray[90000]={3,2,1,4,4,5,6,8,2,4};
for(int i=90000-1;i!=-1;--i)
{
intArray[i]=i;
}
quickS2(intArray,intArray+90000-1);
// for(int i=0;i!=9;++i)
// {
// cout<<intArray[i]<<endl;
// }
return 0;
}
//递归
void quickS(int* left,int* right)
{
if(left<right)
{
int* compareP=left;
for(int * p=left+1;p<=right;++p)
{
if(*p<*compareP)
{
int temp=*p;
for(int * movep=p;movep>compareP;--movep)
{
*movep=*(movep-1);
}
*compareP=temp;
++compareP;
}
}
quickS(left,compareP-1);
quickS(compareP+1,right);
}
else
{
//临界点.求解完毕.
}
}
//
//注意2点.
//递归总体就2个情况.递归调用和到达临界点.一般是if else.
//所以2中情况的结尾.都相当于函数执行了一次.那么.
//1)临界点,需要pop.相当于一次函数返回.
//2)非临界点, 在调用递归前.也必须pop一次.本来是放在调用后面,也就是函数结束.但是这里不是递归,语句不会执行完递归,返回这里.
//所以必须在在模拟递归前先模拟函数返回.
void quickS2(int* left,int* right)
{
stack<int*>* recursion_stack=new stack<int*>();
//初始参数入栈
recursion_stack->push(right);
recursion_stack->push(left);
bool start=true;
while(!recursion_stack->empty())
{
start=false;
left=recursion_stack->top();
recursion_stack->pop();
right=recursion_stack->top();
recursion_stack->push(left);
if(left<right)
{
int* compareP=left;
for(int * p=left+1;p<=right;++p)
{
if(*p<*compareP)
{
int temp=*p;
for(int * movep=p;movep>compareP;--movep)
{
*movep=*(movep-1);
}
*compareP=temp;
++compareP;
}
}
//原一次递归调用完毕,函数返回时,会返回到上一层函数,这里必须在模拟递归前先模拟函数返回.
recursion_stack->pop();
recursion_stack->pop();
//模拟递归
recursion_stack->push(compareP-1);
recursion_stack->push(left);
//模拟递归
recursion_stack->push(right);
recursion_stack->push(compareP+1);
}
else
{
//模拟函数返回
recursion_stack->pop();
recursion_stack->pop();
}
}
}