- 什么是递归
在定义一个过程或函数时,出现直接或者间接调用自己的成分,称之为递归。
若直接调用自己,称之为直接递归。
若间接调用自己,称之为间接递归。
直接递归函数示例:求n!(n为正整数)
int fun(int n)
{ if (n==1) //语句1
return 1; //语句2
else //语句3
return n*fun(n-1); //语句4
}
间接递归示例:
void f1(...)
{
...
f2(...);
...
}
void f2(...)
{
...
f1(...);
...
}
如果一个递归函数中递归调用语句是最后一条执行语句,则称这种递归调用为尾递归。
example:
int fun(int n)
{ if (n==1) //语句1
return 1; //语句2
else //语句3
return n*fun(n-1); //语句4
}
尾递归算法:可以用循环语句转换为等价的非递归算法
其他递归算法:可以通过栈来转换为等价的非递归算法
何时使用递归
在以下三种情况下,常常要用到递归的方法。
-
- 定义是递归的
有许多数学公式、数列等的定义是递归的。
例如,求n!和Fibonacci数列等。这些问题的求解过程可以将其递归定义直接转化为对应的递归算法。
- 定义是递归的
-
- 数据结构是递归的
有些数据结构是递归的。例如,第2章中介绍过的单链表就是一种递归数据结构,其结点类型定义如下:
- 数据结构是递归的
typedef struct LNode
{ ElemType data;
struct LNode *next;
} LinkNode;
3、问题的求解方法是递归的
Hanoi问题:X、Y和Z的塔座,在塔座X上有n个直径各不相同,从小到大依次编号为1~n的盘片。要求将X塔座上的n个盘片移到塔座Z上。
每次只能移动一个盘片;
盘片可以插在X、Y和Z中任一塔座上;
任何时候都不能将一个较大的盘片放在较小的盘片上方。
.
递归算法的设计