递归与栈

登斯楼也,则有去国怀乡,忧谗畏讥,满目萧然,感极而悲者也。
                            ——《岳阳楼记》

一、递归:

  简单来说,递归就是自己调用自己,然后一层一层的返回。
  所有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());  //输出数据
     }
}

所有函数执行的时候,扫描源代码,都是从尾部扫描把数据压入栈中,然后从上往下取数据。后进先出。

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/qicheng777/article/details/76038299
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞