遞歸確實是很多算法的基礎思想。但外部因素導致遞歸會棧溢出。
但卻是不甘心如此簡練的有效的算法,放棄不用。
所以一般有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();
}
}
}