数据结构---递归

递归

递归对于编程的重要性

  • 递归对你的编码能力是个质的飞跃,如果你想成为一个很厉害的程序员,数据结构是必须要掌握的,计算机特别适合用递归的思想来解决问题,但是我们人类用递归的思想来考虑问题就会感到十分困扰,这也是很多学过递归的人一直都搞不明白的地方!递归的思想是软件思想的基本思想之一,在树和图论上面,几乎全是用递归来实现的,最简单,像求阶乘这种没有明确执行次数的问题,都是用递归来解决。

递归的定义

  • 一个函数自己直接或间接调用自己(一个函数调用另外一个函数和他调用自己是一模一样的,都是那三步,只不过在人看来有点诡异。)

函数调用的详解

在一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:

  1. 将所有的实际参数,返回地址等信息传递给被调函数保存;
  2. 为被调函数的局部变量(也包括形参)分配存储空间;
  3. 将控制转移到被调函数的入口。

被调函数返回主调函数之前,系统也要完成三件事:

  1. 保存被调函数的返回结果;
  2. 释放被调函数所占的存储空间;
  3. 依照被调函数保存的返回地址将控制转移到调用函数。

当有多个函数互相调用时,按照“”后调用先返回“”的原则,上述函数之间信息传递和控制转移必须借助“”栈“”来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储区,进行出栈操作当前运行的函数永远都在栈顶位置。

A函数调用A函数和A函数调用B函数在计算机看来是没有任何区别的,只不过用我们日常的思维方式理解比较怪异而已!

递归满足的三个条件

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

循环和递归的比较

递归:

  • 容易理解
  • 速度慢
  • 存储空间大

循环:

  • 不容易理解
  • 速度快
  • 存储空间少

理论上循环能解决的,肯定可以转化为递归,但是这个过程是复杂的数学转化过程,递归能解决不一定能转化为循环,有没有能力运用看个人。

用递归解决汉诺塔问题

在这里插入图片描述
伪算法:

if(n > 1)
{
    
    
	//先把A柱子上的前n-1个盘子从A借助C移动B
	//将A柱子上的第n个盘子直接移到C
	//再讲B柱子上的n-1个盘子借助A移到C
}

具体实现:

扫描二维码关注公众号,回复: 11981075 查看本文章
#include <stdio.h>
#include <stdlib.h>

void hannuota(int n,char A,char B,char C)
{
    
    
/*如果是一个盘子,直接从A柱子上的盘子从A移到C
否则,将A柱子上的n-1个盘子借助C移到B.直接将A柱子上的盘子从A移到C,
最后将B柱子上的n-1个盘子借助A移到C*/

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

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

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

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

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41782149/article/details/92843197