登斯楼也,则有去国怀乡,忧谗畏讥,满目萧然,感极而悲者也。
——《岳阳楼记》
一、递归:
简单来说,递归就是自己调用自己,然后一层一层的返回。
所有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[n] < a[n+1]; //递归终止
}
else
{
return ( a[n] < 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()); //输出数据
}
}
所有函数执行的时候,扫描源代码,都是从尾部扫描把数据压入栈中,然后从上往下取数据。后进先出。