专题:递归

递归

  • 一个函数自己直接或间接调用自己

递归要满足的三个条件

  1. 递归必须得有一个明确的中止条件
  2. 该函数所处理的数据规模必须在递减
  3. 这个转化必须是可解的

循环和递归

  • 递归:易于理解、速度慢、存储空间大
  • 循环:不易理解、速度快、存储空间小

举例

  1. 求阶乘
  2. 1+2+3+4+...100的和
  3. 汉诺塔
  4. 走迷宫

递归的应用

  • 数和森林就是以递归的方式定义的
  • 数和图很多算法都是以递归来实现的
  • 很多数学公式就是以递归的方式定义的

代码

//不同函数之间的调用  

#include <stdio.h>
#include <stdlib.h>

void f();
void g();
void k();

void f()
{
    printf("FFFF\n");
    g();
    printf("1111\n");
}

void g()
{
    printf("GGGG\n");
    k();
    printf("2222\n");
}

void k()
{
    printf("KKKK\n");
}

int main(void)
{
    f();

    system("pause");
    return 0;
}

代码

//自己调用自己  

#include <stdio.h>
#include <stdlib.h>

void f(int n)
{
    if(n ==1)
    printf("哈哈\n");
    else
    f(n-1);
}

int main(void)
{
    f(3);

    system("pause");
    return 0;
}

举例

  1. 求阶乘
  2. 1+2+3+4+...+100的和
  3. 汉诺塔
  4. 走迷宫

代码

//阶乘的循环实现.cpp

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int val;
    int i, mult=1;

    //printf("请输入一个数字: ");
    printf("val = ");
    scanf("%d", &val);

    for(i=1; i<=val; ++i)
        mult = mult * i;

    //printf("%d的阶乘是:%d\n",val,mult);
    printf("%d\n",mult);

    system("pause");
    return 0;
}

代码

//阶乘的递归实现.cpp

#include <stdio.h>
#include <stdlib.h>

//假定n的值是1或大于1的值
long f(long n)
{
    if(1 == n)
    return 1;
    else
    {
        return f(n-1)*n;
    }
    
}

int main(void)
{
    printf("%ld\n",f(4) );

    system("pause");
    return 0;
}

代码

//1+2+3+4...+100的和用递归实现.cpp

#include <stdio.h>
#include <stdlib.h>

long f(long n)
{
    if(1 == n)
    return 1;
    else
    {
        return f(n-1)+n;
    }
    
}

int main(void)
{
    printf("%ld\n",f(100) );

    system("pause");
    return 0;
}

代码

//汉诺塔.cpp

#include <stdio.h>
#include <stdlib.h>

//如果是一个盘子
//直接将A柱子上的盘子从A移到C
//否则
//先将A柱子上的(n-1)个盘子借助C移到B
//直接将A柱子上的盘子从A移到C
//最后将B柱子上的(n-1)个盘子借助A移到C

void hanoi(int n, char A, char B, char C)
{
    if(1 == n)
    {
        printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
    }
    else
    {
        hanoi(n-1, A, C, B);
        printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
        hanoi(n-1, B, A, C);
    }
    
}

int main(void)
{
    char ch1 = 'A';
    char ch2 = 'B';
    char ch3 = 'C';
    int n;

    printf("请输入要移动盘子的个数:");
    scanf("%d", &n);

    hanoi(n,'A','B','C');

    system("pause");
    return 0;
}