2.1.5受限制顺序表_栈_栈的应用(递归)+迷宫问题

本文介绍了递归算法的书写步骤,并通过斐波那契数列、阶乘函数和汉诺塔问题展示了递归的应用。此外,还探讨了使用栈和回溯策略解决迷宫问题的方法,提供了一个迷宫问题的深度优先搜索解决方案。
摘要由CSDN通过智能技术生成

一.递归的书写步骤

先再草稿纸上写下通项公式,然后再进行算法实现
一般条件,减少层次量,终止条件

二.常用递归算法

1.斐波那契数列

//斐波那契数列
#include <iostream>
using namespace std;
int Fib(int n)
{
    if (n <= 1)
        return n;
    else
        return Fib(n - 2) + Fib(n - 1);
}
int main()
{
    int num;

    cout << "请输入计算的层次数:"<<endl;
    cin >> num ;
    int res = Fib(num);
    cout << "得到的得数为:" << res << endl;

    return 0;
}

2.阶乘

int Fac(int n)
{
    if (n <= 1)
        return n;
    else
        return n*Fac(n-1);
}

3.汉诺塔问题

数学描述:
有三根杆子X,Y,Z。X杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至Y杆:

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

递归思想:

  1. 将X杆上的n-1个圆盘都移到空闲的Z杆上,并且满足上面的所有条件
  2. 将X杆上的第n个圆盘移到Y上
  3. 剩下问题就是将Z杆上的n-1个圆盘移动到Y上了

代码实现:

//用栈实现汉诺塔问题
#include <iostream>
//参数:问题规模,参数的使用方向
using namespace std;
void hanoi(int n, char from, char tmp, char to)
{
    if (n > 0)
    {
        hanoi(n - 1, from, to, tmp);
        cout << "拿走" << n << "从" << from << "到" << to << endl;
        hanoi(n - 1, tmp, from, to);
    }
}

int main()
{
    char from = 'A';
    char tmp = 'B';
    char to = 'C';
    int n = 3;
    hanoi(3, from, tmp, to);
    return 0;
}

看到的资料:汉诺塔及常见的递归问题整理

三.迷宫问题

问题较难,估计不会进行考察
先设定二维数组进行地图存储,然后对设定一个二维数组表示可移动的方向,之后进行四个方向的调查
若为障碍物1则回溯,若0则可以走,继续探索,当走到拐角,将判断标志位置为真,将对应路径进行存储
输出时进行出栈处理

总的来说可以使用 栈,回溯,递归的思想

实例代码:

//
// Created by 19a406 on 2023/4/14.
//
#include <iostream>
#include<algorithm>
#include <stack>
using namespace  std;
//迷宫问题的常见解法
int main(){
    //二级数组的定义方法
    int N,M;
    while(cin>>N>>M){
        //二级指针
        int **a=new int*[N];
        for(int i=0;i<N;i++){
            a[i]=new int[M];
        }
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                cin>>a[i][j];
            }
        }
        //行走的四个方向
        int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
        int visit[11][11]={0};
        bool flag=0;//是否走完
        stack<pair<int,int>> stk;
        stk.push(make_pair(0,0));
        stk.push(make_pair(0,0));
        visit[0][0]=1;
        //深度优先搜索,往四个角探查,有则继续探查,没有则回溯
        while(!flag){
            pair<int,int> p=stk.top();
            stk.pop();
            //初始从0开始(0,0)
            int i=p.first;
            int j=p.second;
            for(int k=0;k<4;k++){
                //最开始从0,0往y坐标走一个格子
                int dx=i+dir[k][0];
                int dy=j+dir[k][1];
                //走到了出口
                if(dx==N-1&&dy==M-1){
                    stk.push(make_pair(N-1,M-1));
                    flag=true;
                    break;
                }
                //确认走的那个格子的状态,a[][]==0,表示这个不是障碍物,还在visit观测的里面
                if(dx>=0&&dx<=N-1&&dy>=0&&dy<=M-1&&a[dx][dy]==0&&visit[dx][dy]==0){
                    //未被访问过且有路径
                    stk.push(make_pair(dx,dy));
                    //visit的数组不是很明白
                    visit[dx][dy]=1;
                    i=dx;
                    j=dy;
                    k=-1;
                }
            }
        }
        stack<pair<int,int>> outputStk;
        while (!stk.empty()){
            outputStk.push(stk.top());
            stk.pop();
        }
        cout<<"可以行走的路径"<<endl;
        while(!outputStk.empty()){
            pair<int,int> p=outputStk.top();
            outputStk.pop();
            //p是可以走的路线
            cout<<"("<<p.first<<","<<p.second<<")"<<endl;
        }
    }
    return 0;
}

链接:迷宫描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值