小白思路:DFS走迷宫

算法思想

DFS:深度优先搜索,采用递归方式进行搜索,为了方便记录搜索过程,使用链栈记录每次访问的节点。搜索到最底层或死胡同则返回上一层,直到找出所有可能的路径。定义搜索顺序为:右、下、左、上。

注意

  1. 本算法使用自定义结构体,没有使用stack方法。
  2. 分清楚指针、指向指针的指针、引用变量、实体的区别以及他们的联系。
  3. 如果为一个指针申请了空间,则一定要初始化空间为NULL,否则会有一大堆混乱。push()方法是将一个新节点插入到原来的链栈里,而不是为原来的栈节点赋值。所以如果不先为申请的空间赋NULL,则该节点空间会乱指。
  4. 在实际跑的过程中,发现如果只定义栈的指针,并且不申请空间,则不用赋NULL;如果申请开辟空间了,则在使用前一定要先为空间赋NULL。即:LinkStack L;等价于LinkStack L = new StackNode; L = NULL;具体为什么猜测为空间不初始化会乱指,并且如果你不初始化空间,则计算机会默认给他赋一个值,这样申请的几个堆栈空间全部重叠在一起了,会出现异常。
  5. 因为是链栈,所以很容易出现nullptr空指针问题,因为在不断pop()中很有可能全出栈了,这时候如果想要打印栈则会出现问题。方法是将打印移到pop()前。(这个问题主要是在一开始写的一团乱麻的时候遇到和后来改bug加了很多打印的时候遇到)
  6. 本方法使用不带头结点的链栈,如果需要,带头结点的也是可以的。
  7. 入栈出栈一一对应,包括step的加减,不能忘记写。
  8. 写代码的思路一定要清晰,写着写着可能就糊涂了。因此检查代码的时候力求冷静,不能发癫,检查的步骤应该用代码本身自己跑出来的过程,而不是自己手写的过程。

 插个题外话,感觉自己真的很不适合写代码,小小的迷宫问题前前后后写了一周,虽然不是一直都在写,也有干别的事,但是差不多也是花了这么多时间,并且每次出现错误都是自己先崩溃,根本找不到错误在哪,只能寻求他人的帮助。在这里非常感谢耐心帮我看代码改bug的人,并且教会了我找bug的基本方法。(虽然还是不会用打断点的方法找bug,不知道写一个这样简单的程序能不能用打断点的方法呢?欢迎各位大佬点评)

代码实现

这里是我自己重新写的代码,所以没那么多乱七八糟注释,等有时间贴过程。主要是写代码的过程真的是乱七八糟惨不忍睹,我都不忍心再看。。。

代码(纯享版)


#include<iostream>
#include<stdio.h>
#include<malloc.h>

using namespace std;

int map[8][8] =
{
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 0},
    {0, 0, 0, 1, 0, 0, 0, 0},
    {1, 1, 0, 1, 0, 1, 1, 0},
    {0, 0, 0, 1, 0, 0, 1, 1},
    {0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0}
};

struct record
{
    int r;
    int c;
};

typedef struct StackNode
{
    record data;
    StackNode* next;
}StackNode, * LinkStack;

LinkStack S;
LinkStack S1;
LinkStack S2;
//LinkStack S = new StackNode;
//LinkStack S1 = new StackNode;
//LinkStack S2 = new StackNode;

//int step;
int num = 0;
int MIN = 9999;

//void InitStack(LinkStack& S)
//{
//    S->next = NULL;
//    //S = NULL;
//}

void push(LinkStack& S, record val)
{
    //使用了new申请空间,是否需要初始化?
    LinkStack p = new StackNode;
    if (p)
    {
        p->data = val;
        p->next = S;
        S = p;
    }
}

bool StackEmpty(LinkStack& S)
{
    if (S == NULL)
        return 1;
    else
        return 0;
}

void pop(LinkStack& S)
{
    if (!StackEmpty(S))
    {
        //使用了new,是否需要初始化?
        LinkStack temp = new StackNode;
        temp = S;
        S = S->next;
        delete(temp);
    }
}
void print(int step)
{
    //S1 = NULL;
    //S2 = NULL;
    cout << "长度: " << step << endl;
    while (!StackEmpty(S))
    {
        push(S1, S->data);
        push(S2, S->data);
        pop(S);
    }
    while (!StackEmpty(S1))
    {
        push(S, S1->data);
        pop(S1);
    }
    while (!StackEmpty(S2))
    {
        cout << "(" << S2->data.r << "," << S2->data.c << ")    ";
        pop(S2);
    }
}

void dfs(int row, int col, int x, int y, int step)
{
    //cout << "\ndfs(" << row << "," << col << ")" << endl;
    //cout << "map[" << row << "][" << col << "]=" << map[row][col] << endl;
    //cout << "step测试: " << step << endl;
    record d{};
    d.r = row;
    d.c = col;
    if ((row == x) && (col == y))
    {
        cout << "min: " << MIN << "    step: " << step << endl;
        if (step < MIN)
            MIN = step;
        cout << "min: " << MIN << "    step: " << step << endl;
        cout << "\n最小" << MIN << "步" << endl;
        num++;
        cout << "\n第" << num << "次" << endl;
        //cout << "push(" << row << "," << col << ")" << endl;
        push(S, d);
        print(step);
        //cout << "pop(" << S->data.r << "," << S->data.c << ")" << endl;
        pop(S);
        //cout << "return" << endl;
        return;
    }

    if ((row < 0) || (col < 0) || (row > 7) || (col > 7))
    {
        //cout << "return" << endl;
        return;
    }
        

    if (map[row][col] == 0)
    {
        map[row][col] = -1;
        //cout << "push(" << row << "," << col << ")" << endl;
        //cout << "map[" << row << "][" << col << "]=" << map[row][col] << endl;
        push(S, d);
        //一定是++step和--step而不是step++和step--,否则不会改变step值
        dfs(row, col + 1, x, y, ++step);
        --step;
        dfs(row + 1, col, x, y, ++step);
        --step;
        dfs(row, col - 1, x, y, ++step);
        --step;
        dfs(row - 1, col, x, y, ++step);
        --step;
        map[row][col] = 0;
        //cout << "pop(" << S->data.r << "," << S->data.c << ")" << endl;
        pop(S);
    }
}

int main()
{
    //S = NULL;
    cout << "请输入终点位置" << endl;
    int m, n;
    cin >> m >> n;
    dfs(0, 0, m, n, 1);
}

运行结果

这个迷宫任何点的走法都实在是太多了,没办法贴出完整代码。最后运行格式也不好看,大概是这样子:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值