美文网首页
数据结构与算法9-递归

数据结构与算法9-递归

作者: fuaiyi | 来源:发表于2020-04-15 21:50 被阅读0次

    递归方法就是直接或者间接的调用自己,它可以将一些发杂问题简化。

    递归在下列方法中经常会用到:

    • 定义是递归的。

    如斐波拉契数列、阶乘等。

    • 数据结构是递归的。

    数据结构本身具有递归性,如链表、树等。

    • 问题的解法是递归的。

    有一类问题,虽然问题本身没有明显的递归结构,但采用递归求解比迭代求解更简单。如汉诺塔问题、八皇后问题、迷宫问题。

    所有的递归都能用循环解决

    分治法

    在求解4!时,我们会先求解3!,然后再进一步分解进行求解,这种求解叫做分治法

    使用分治法需要满足3个条件:

    • 能将一个问题转换成一个小问题,新问题和原问题的解法相同或类同。不同的只是被处理的对象,并且这些处理更小且变化是有规律的。
    • 可以通过上述转换而使得问题简化。
    • 必须有一个明确的递归出口,或成为递归边界。
    汉诺塔问题

    在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。

    移动圆盘时受到以下限制:

    • 每次只能移动一个盘子;
    • 盘子只能从柱子顶端滑出移到下一根柱子;
    • 盘子只能叠在比它大的盘子上。

    解决思路
    我们使用递归来解决:

    • n=1时,直接把盘子从A移动到C就行了。(递归边界)
    • n>1时:
      • 先把n-1个盘子从A移动到B;(子问题,递归)
      • 将最大的盘子从A移动到C;
      • 再将B上n-1个盘子移动到C。(子问题,递归)
    用栈解决
    static void move(LinkStack *A, LinkStack *B, LinkStack *C, int n) {
        if (n == 1) {
            int elem;
            Pop(A, &elem);
            Push(C, elem);
        } else {
              // 把栈A中n-1个盘子放到栈B
            move(A, C, B, n - 1);
            // A栈出栈放入C栈
            int elem;
            Pop(A, &elem);
            Push(C, elem);
              // 把栈B中n-1个盘子放到栈C
            move(B, A, C, n - 1);
        }
    }
    
    void hanoi(LinkStack *A, LinkStack *B, LinkStack *C) {
        move(A, B, C, StackLength(*A));
    }
    
    int main(int argc, const char * argv[]) {
        int n = 5;
        LinkStack A, B, C;
        InitStack(&A);
        InitStack(&B);
        InitStack(&C);
        for (int i = n; i > 0; i--) {
            Push(&A, i);
        }
        printf("原始栈A:");
        StackTraverse(A);
        printf("原始栈C:");
        StackTraverse(C);
        
        hanoi(&A, &B, &C);
        
        printf("移动后栈A:");
        StackTraverse(A);
        printf("移动后栈C:");
        StackTraverse(C);
        
        return 0;
    }
    // 输出
    原始栈A:1 2 3 4 5 
    原始栈C:
    移动后栈A:
    移动后栈C:1 2 3 4 5 
    
    移动过程
    void hanoi2(char *A, char *B, char *C, int n) {
        if (n == 1) {
            printf("move %s to %s\n", A, C);
        } else {
            hanoi2(A, C, B, n - 1);
            printf("move %s to %s\n", A, C);
            hanoi2(B, A, C, n - 1);
        }
    }
    int main(int argc, const char * argv[]) {
        hanoi2("a", "b", "c", 3);
        return 0;
    }
    // 输出
    move a to c
    move a to b
    move c to b
    move a to c
    move b to a
    move b to c
    move a to c
    
    image.png

    相关文章

      网友评论

          本文标题:数据结构与算法9-递归

          本文链接:https://www.haomeiwen.com/subject/uqqkvhtx.html