递归与while的比较与转换

http://blog.sina.com.cn/s/blog_9d3cc3990101a7nm.html

比较:
while和递归的相同点就是都有循环式地处理相同的某一大块语句,每次循环的运算操作和顺序完全相同.
不同的是,while没有自动入栈功能,不能把上次的循环的变量是先存在另一个空间,以防下次循环处理变量时改变他们,没有入栈,所以也不需出栈,也正因为这样,所以while达到的一个功效就是,每次循环都能将同一空间的变量改变.
那递归,就是函数调用,有入栈,必有出栈,入栈的好处是把变量暂存起来,出指针传值方式外的变量,每次循环处理的变量都是当前的栈空间的变量,这样就不用考虑会影响上一层的变量的值.因为可以自动入栈和出栈,所以相当于模拟了一个将某变量(递归控制变量,相当于循环控制变量)自增或自减.在求n的阶乘的实例中,我们可以看到有f(n-1)*n这个语句,它的执行顺序是先入栈,保存相关变量,执行f(n-1),直到成功返回一个值,才与n相乘,由于函数调用的特点是自动入栈与出栈,所以非指针传值的n的值不会受到f(n-1)的影响.但是while不能够做到这点,它如果进入下次循环,n的值就要被改变了.
总结:可见while和递归这两种编程,各有各的特点,各有各的长处.我们只能说,不同的需要不同的选择罢了.
 

(1)递归转while:

这个没有难度,把递归看成while里的continue,然后关键是参数的传递,除了控制循环其次的变量可以选择性地不用指针传递之外,while里的其他变量都要用指针传值方式,因为while没有入栈暂存变量的必要,所以每次循环改变的变量的值都是同一地址空间的值,指针传值方式就做到了这一点.然后边界条件模拟while的循环次数.来个实例吧:
#include
using namespace std;
int main(void)
{
int a=2;
int i=8;
while(i)
{
  a = a + i;
  i--;
  //此处相当于continue了.
}
return 0;
}
转为递归
#include
using namespace std;
void f(int *a, int i);
{
   if(i==0) return ;//相当于while(i==0) 不进行循环一样
   
   //必要处理
   *a = *a+i;
   i--;
   
   f(a, i);//相当于continue了.
}
int main(void)
{
  int a=2; 
  int i=8;
  f(&a, i);
  return 0;
}
 
转换框架:..............待续
转换代码:................待续

(2)while转递归:
这个也不难,把递归的入栈出栈过程模拟出来就可以了,哪些变量需要入栈,哪些没有必要入栈,这个自己斟酌就好,我的建议是除指针传值方式的变量不用入栈外,其他都要,另外加上一个控制模拟栈的top变量就可以了.递归的特点就是碰到调用就入栈,进入被调函数处理相关运算.碰到出口(返回语句)之后,就是出栈,然后返回上层函数处理.模拟分带返回值类型和非返回值类型.其用while模拟的大概结构如下:
 
实例1:带返回值,
//递归求n的阶层
#include
int fun(int n);
int main(void)
{
int n;
scanf("%d", &n);
printf("%d", fun(n));
return 0;
}

int fun(int n)
{
if(n=0)
return 1;
else
return fun(n-1)*n;
}

//非递归算法
#include
int fun(int n);
int main(void)
{
int n;
scanf ("%d", &n);
printf("%d", fun(n));
return 0;
}

int fun(int n)
{
T stack[2*n+1];
int top =0;
A addr;
int s;
L1:if(n==0)
s = 1;
else
{
stack[++top]=n;
stack[++top] =L2;
n--;
goto L1;
L2:s=stack[top--];
s=s*n;
}
if(top==0) return s;
else
{
addr = stack[top--];
n = stack[top--];
stack[++top] = s;
if(addr==L2)
goto L2;
}
}

//goto结构转为循环结构
#include
int fun(int n);
int main(void)
{
int n;
scanf("%d", &n);
printf("%d", fun(n));
return 0;
}

int fun(int n)
{
T stack[n+1];A addr;int top=0;
int s;
while(1)
{
if(n==0)
s=1;
else
{
stack[++top]=n;
n--;
continue;
}
while(1)
{
if(top==0)
return s;
else
{
n = stack[top--];
stack[++top] = s;
s = stack[top--];
s = s*n;
continue;
}
}
}
}
 
实例二:不带返回值的转换类型,
//递归写法
#include
void hanoi(int n,int x, int y,int z);
int main(void)
{
int n;
int ch[3]={1,2,3'};
scanf("%d", &n);
hanoi(n,ch[0],ch[1],ch[2]);
return 0;
}

void hanoi(int n, int x, int y, int z)
{
if(n==1)
printf("%d to %d\n", x, z);
else
{
hanoi(n-1, x, z, y);
printf("%d to %d\n", x, z);
hanoi(n-1, y, x, z);
}
}

//goto结构非递归
#include
#include
void hanoi(int n, int x, int y, int z);
int main(void)
{
int n;
int ch[3] = {1, 2, 3};
scanf("%d", &n);
hanoi(n, ch[0], ch[1], ch[2]);
return 0;
}

void hanoi(int n, int x, int y, int z)
{
int *stack = (int *)malloc(sizeof(int)*n*5+1);
int ch;
int addr;
int top=0;
L1:if(n==1)
printf("%d to %d\n", x, z);
else
{
stack[++top] = n;
stack[++top] = x;
stack[++top] = y;
stack[++top] = z;
stack[++top] = 2;
n --; x = x; ch = y; y = z; z = ch;
goto L1;
L2:printf("%d to %d\n", x, z);
stack[++top] = n;
stack[++top] = x;
stack[++top] = y;
stack[++top] = z;
stack[++top] = 3;
n --; ch = x; x = y; y = ch; z = z;
goto L1;
L3: ;
}
if(top==0) return ;
else
{
addr = stack[top--];
z = stack[top--];
y = stack[top--];
x = stack[top--];
n = stack[top--];
if(addr == 2)
goto L2;
else goto L3;
}

}

//goto 结构转为循环结构
#include
#include

void hanoi(int n, int x, int y, int z);

int main(void)
{
int n;
int ch[3] = {1,2,3};
scanf("%d", &n);
hanoi(n, ch[0], ch[1], ch[2]);
return 0;
}

void hanoi(int n, int x, int y, int z)
{
int *stack = (int *) malloc(sizeof(int)*5*n+1);
int top=0;
int addr;
int temp;
while(1)
{
if(n==1)
printf("%d to %d \n", x, z);
else
{
stack[++top] = n;
stack[++top] = x;
stack[++top] = y;
stack[++top] = z;
stack[++top] = 2;
n--; x = x; temp = y; y = z; z = temp;
continue;
}
while(1)
{
if(top==0) return ;
else
{
addr = stack[top--];
z = stack[top--];
y = stack[top--];
x = stack[top--];
n = stack[top--];
if(adrr==2)
{
printf("%d to %d\n", x, z);
stack[++top] = n;
stack[++top] = x;
stack[++top] = y;
stack[++top] = z;
stack[++top] = 3;
n--; temp = x; x = y; y = temp; z = z;
break;
}
else continue;
}
}
}
}
模拟框架:................待续
转换代码:....................待续
 
//这里不想总结了,你还可以写一个程序出来,把这两转换过程实现出来.我还没有写出来.其规律自己找,不想重复.
posted @ 2016-08-02 11:03  liness0713  阅读(2151)  评论(0)    收藏  举报