杨新宇 兰全祥
摘要:函数以及函数的递归调用是学习C语言必须要掌握的内容,且递归作为经典的算法思想被广泛应用于程序设计中。从应用场景的角度出发,对C语言中递归的定义、特征以及适用场景进行了探讨,并对这些适用场景进行分析和举例。最后,分析并探讨了递归的优缺点,并给出了递归的优化方法和将递归转换为非递归的方法。
关键词:C语言;递归;应用;非递归化
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2020)22-0237-02
开放科学(资源服务)标识码(0SID):
1 背景
随着时代的进步以及计算机编程语言的不断发展,从20世纪80年代传承至今的C语言始终是各大高校首选的计算机编程语言。世界编程语言排行榜( TIOBE)中C语言的热门程度自2002年至今始终稳居前三[1]。由此可见,C语言的重要程度以及热门度。另外,模块化设计是所有程序设计必须遵循的设计原则,而函数就是C语言模块化的重要组成部分[2]。C语言函数以及函数的使用是学习C语言必须要掌握的内容。递归作为经典的函数使用方法,应用范围广泛,是函数中不可或缺的重要内容,也是作为一个开发者应该掌握的重要算法之一。
2 遞归的概述
2.1 定义
张长海等人认为在定义一个函数时,若在定义函数的内部又出现对函数本身的调用,则称该函数是递归的或递归定义的[3];谭浩强等人认为递归就是函数自己直接或间接地调用自身的过程[4];丁雪晶认为递归就是把要解决的问题分解成与原问题有相同解法,且规模较小的问题,直到遇见终止条件[5]。综上,笔者认为函数的递归就是直接或间接地调用自身进行人栈操作,遇到边界之后再进行出栈的过程,且在人栈过程中,由原始问题分解为的子问题始终向边界靠拢。
2.2 特征
从上述定义可得出递归的以下特征:
1)函数总是直接或者间接的调用自身;
2)函数的递归必须有结束条件(即问题的边界),且在调用的过程中始终向某一个边界靠近;
3)递归过程是一个不断人栈和出栈的过程。
2.3 应用场景
递归的本质是将关于n的问题转化为同类解法的关于m的问题,其中n和m是问题的规模,且m比n更靠近问题的边界(递归结束条件)。
通过对常见递归应用的分析,笔者将递归应用场景分为三类:
1)数据的初始化是递归的。
2)数据的结构是递归的。
3)问题的求解是递归的。
3 递归的案例
根据上述对函数递归的定义、特征以及应用场景的总结,本文对上述递归的应用场景进行分析和举例。
3.1 数据的初始化是递归的
示例:Fibonacci数列(兔子数列)
描述:形如1,1,2,3,5,8,13,21I.….的数列被称为Fibonac-Cl数列,即第n个数等于第n-l个数和第n-2个数之和。
分析:根据上述定义,对数列进行数学归纳可得出数学递推公式。
根据分析可知,Fibonacci数列是典型的数据的初始化是递归的例子,即要对n进行初始化,必须知道n-l和n-2的值。
初始化Fibonacci数列的关键代码如下:
int Fib(int n){
if(n ==1¨n==2){return 1;)
elsef
return Fib(n-I)+Fib(n-2);
)
)
3.2 数据的结构是递归的
示例:二叉树
描述:二叉树是结点的有限集合,该集合或者为空集,或者是由一个根和两棵互不相交的称为该根的左子树和右子树的二叉树组成[6]。
分析:由定义可知,一个根结点可能存在左子树和右子树,且左子树和右子树又是一颗更小的二叉树。
因此,二叉树从数据结构上来看是递归的,如图1所示,A的左子树、A的右子树以及C的左子树都是一颗二叉树,且无论是二叉树的初始化还是遍历都能用递归来解决。
构造二叉树的关键代码如下:
typedef struct BiTNode{char data; struct BiTNode,*rchild,*rchild;}BiTNode,a:BiTree;
void CreateBiTree(BiTiree *T){
char c;scanf(”%c”,&c);
i“c==7#7){*T=NULL;】
elsef
*T= (BiTNode*)new BiTNode;
(*T)->data=c;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
)
】
由代码可以看出,在二叉树的构造中,输入根节点数据之后还需要递归调用CreateBiTree函数对其左右子树进行构造,即要成功构造一颗二叉树,需要先构造出其左、右子树。另外,二叉树的遍历也可采用递归的方法实现先序遍历、中序遍历与后序遍历。
3.3 问题的求解是递归的
示例:汉诺塔
描述:现有A,B,C三根柱子,在A柱有n个从上到下面积依次增大的盘子,现在想把A柱这n个盘子移动到C柱,但规定每一次只能移动一个盘子,且三根柱子的盘子始终都保持着面积大的盘子在下,面积小的盘子在上,问盘子移动的步骤。