算法

递归法

定义

若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的;若一个过程直接或间接地调用自己,则称这个过程是递归的过程。

递归的三种情况:定义是递归的、数据结构是递归的、问题的解法是递归的。

递归的特点:递归至少存在一个出口、函数内部自己调用自己。

问题举例

阶乘

阶乘的定义:

$$ n! = \left\{ \begin{array}{c} 1, & n = 0 \\ n \cdot (n-1)!, & n \geqslant 1 \end{array} \right.$$

可知阶乘的定义是递归的。

1long long Factorial(long long n) {
2    if (n == 0) {
3        return 1;
4    }
5    else {
6        return n * Factorial(n-1);
7    }
8}

查找链表的元素

定义链表:

1struct Node {
2    ElemType data;
3    Node *next;
4};

可知链表的数据结构是递归的。

 1void Search(Node *f, ElemType e) {
 2    if (f != NULL) {
 3        if (f->data == x) {
 4            printf("%d\n", f->data);
 5        }
 6        else {
 7            Search(f->next, e);
 8        }
 9    }
10    return;
11}

汉诺塔问题

问题概述:假设有3个分别命名为 $x$,$y$,$z$ 的塔座,在塔座 $x$ 上插有 $n$ 个直径大小各不相同、依次编号为 $1,2,3,…,n$ 的圆盘。现要求将 $x$ 塔座的 $n$ 个圆盘移动到 $z$ 塔座上且按同样的顺序堆叠。圆盘移动时遵循以下规则:

  1. 每次只能移动一个圆盘。
  2. 圆盘可以放在 $x$,$y$,$z$ 的任意塔座上。
  3. 任何时刻都不能将一个较大的圆盘放在较小的圆盘之上。

汉诺塔

因此,汉诺塔问题的解法是递归的。

 1void hanoi(int n, char x, char y, char z) {
 2    if (n == 1) {
 3        move(x, 1, z);          // 将编号为1的圆盘从x移到z
 4    }
 5    else {
 6        hanoi(n-1, x, z, y);    // 将x上编号为1到n-1的圆盘移到y,z作为辅助塔
 7        move(x, n, z);          // 将编号为n的圆盘从x移到z
 8        hanoi(n-1, y, x, z);    // 将y上编号为1到n-1的圆盘移到z,x作为辅助塔
 9    }
10}
Licensed under CC BY-NC-SA 4.0
网站总访客数:Loading

使用 Hugo 构建
主题 StackJimmy 设计