您的位置:首页 > 编程语言

递归与栈

2017-07-25 10:30 78 查看
登斯楼也,则有去国怀乡,忧谗畏讥,满目萧然,感极而悲者也。

                            ——《岳阳楼记》

一、递归:

  简单来说,递归就是自己调用自己,然后一层一层的返回。

  所有for循环都可以用递归来做。

废话不多说,直接上例题:

1、实例1:

50个台阶,一次只能走一步或者两步,问有多少方法到达第10个台阶?



解决这个方法,我们首先要找到数学规律:

f(10)=f(9)+f(8)

f(9)=f(8)+f(7)

f(n) = f(n-1)+f(n-2)

首先用数组的方法来解决:

//用数组来计算:
#include <stdio.h>
void main()
{
double a[50];
a[0]=1;
a[1]=2;
for (int i=2;i<50;i++)
{
a[i]=a[i-1]+a[i-2];
printf("%f\n",a[i]);
}
}


用递归来解决:

#include <stdio.h>
double go(int n)
{
if ( n == 1)
{
return 1;
}
else if( n == 2)
{
return 2;
}
else
{
return go(n-1)+go(n-2);
}
}

void main()
{
printf("%f",go(10));
}


2、实例2:

递归法判断一个数组是否为递增:

#include <stdio.h>
int a[10]={1,2,3,4,5,6,7,8,9,10};
int isadd(int n)
{
if(n == 8)
{
return a
< a[n+1];   //递归终止
}
else
{
return ( a
< a[n+1])  &&  isadd(n+1) ;  //把所有判断循环串联起来
}
}

void main()
{
printf("%d",isadd(0));  //如果是递增打印返回值1,递减打印0
}


3、实例3 :

  函数实现十进转换成二进制。

void tentotwo(int num)
{
if(num!=0)
{
int m=num%2;
num=num/2;
tentotwo(num);    //递归
printf("%d",m);   //放在递归函数下方,逆序。放在上方,顺序
}
}

int main()
{
tentotwo(10);
}


  最后打印的结果为1010 。逆序打印。

  如果把printf放在tentotwo(num);之前,则打印的是0101,顺序打印。



中间那条线表示函数的调用,细线表示函数逆序返回。

二、栈:

遵循后进先出的原则。




简单的实例:

逆序输出数组

#include <stdio.h>
#include <stdlib.h>
#define LEN 50
typedef struct mystack   //定义栈
{
int top;          //栈顶
int data[LEN];    //数据区
};

struct mystack selfstack ={-1, {0} };  //初始化栈顶,数据

int isempty ();      //检测栈是否为空
void setempty();     //将栈设置为空
int push(int num);   //压入数据
int pop();           //取出数据

int isempty()
{
if(selfstack.top == -1)   //top=-1,栈为空
{
return 1;
}
else
{
return 0;
}
}

void setempty( )
{
selfstack.top == -1;   //设置栈为空
}

int push(int num)
{
if(selfstack.top == LEN-1 )  //栈溢出
{
printf("the stack is full!");
return -1;
}
selfstack.top+=1;   //下标往前移动
selfstack.data[ selfstack.top] = num;   //数据存入
return 0;
}

int pop( )
{
if(selfstack.top == -1)
{
printf("the stack is empty!");
return -1;//栈为空
}
else
{
selfstack.top  -=1;
return selfstack.data[selfstack.top+1]; //因为top最小值为-1,而数组最小只能取到0,所以这里要加1
}
}

void main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int i;
for(i=0;i<10;i++)
{
push(a[i]);   //压入数据
}
while( !isempty() )
{
printf("%d ",pop());  //输出数据
}
}


输出结果:10 9 8 7 6 5 4 3 2 1

我们也可以用栈的方法来实现上文将十进制转换成二进制

void main()
{
int num=100;

while(num)
{
push(num%2);
num/=2;
}

while( ! isempty() )
{
printf("%d",pop());  //输出数据
}
}


所有函数执行的时候,扫描源代码,都是从尾部扫描把数据压入栈中,然后从上往下取数据。后进先出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息