递归和栈溢出。

Posted 琴鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归和栈溢出。相关的知识,希望对你有一定的参考价值。

递归确实是很多算法的基础思想。但外部因素导致递归会栈溢出。

但却是不甘心如此简练的有效的算法,放弃不用。

所以一般栈类型放入参数,模拟递归调用。

用快速排序,测试并总结了下。

1)本例大概 排序30000个数字,递归就溢出。

2)用局部变量的栈类型。也不超过90000个数字。

3)栈类型用指针,放入堆中。到此问题解决。

不明白为什么要new。

stack<int*>* recursion_stack=new stack<int*>();

stack<int*> recursion_stack;

这2个数据不都是放在堆中吗?。。。

 

 

#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();
}
}
}

以上是关于递归和栈溢出。的主要内容,如果未能解决你的问题,请参考以下文章

如何解决栈溢出

堆和栈

内存溢出与内存泄露知识点总结

Java如何在不使用递归的情况下导致栈溢出?

栈溢出原理

栈溢出解决