数据结构与算法9-递归

2020-04-15  本文已影响0人  fuaiyi

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

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

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

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

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

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

分治法

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

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

汉诺塔问题

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

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

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

用栈解决
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
上一篇 下一篇

猜你喜欢

热点阅读