数据结构一直都是专业课里面比较难的一门课程,因为里面涉及到了很多算法知识。这也给大家造成了一个困扰,是不是智商不行就学不了数据结构?

显然不是!算法知识确实很难,但是我们在学习的过程中很少会去开发新的算法,基本上都是在别人的成果上加以探索。其实只要是愿意花时间,善于归纳总结,我们还是能发现很多算法的规律。看的多了,就很容易在解决实际问题的时候联想到对应的算法。

直奔主题吧。栈结构我们在之前的课堂上给大家讲过,还写了用栈解决四则运算的代码,代码不简单,我相信也让不少小伙伴奔溃。我们今天继续用栈来解决问题,而且解决的是一个非常著名的算法–深度优先算法(Depth First Search),简称DFS。

DFS是图里面的一种遍历算法。提到图,大家又被吓的一激灵,这可是比树还要难的模型啊。别紧张,图确实很难,但是早就有人把它总结出来了,只要套用固定的算法,还是可以解决的。我们还是先看看DFS是怎么回事吧。

DFS简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次,等到发现不能再深入了,再回头换一条路探索。啥玩意?看看下面的例子:

对于这种结构,DFS方法首先从根节点1开始,其搜索节点顺序是1,2,3,4,5,6,7,8。

步骤如下:
1、访问第一个节点,并且把第一个节点入栈

2、找出与此点邻接的且尚未遍历的点,进行标记,然后放入stack中,依次进行;


3、如果此点没有尚未遍历的邻接点,则将此点从stack中弹出,再按照2依次进行。比如第5个节点进栈后,找不到合适的下一个节点,把第5个节点弹出,再去寻找第4个节点的另一条出路。



4、直到遍历完整个树,stack里的元素都将弹出,最后栈为空,DFS遍历完成。



我们再来看一个深度优先算法的典型应用:迷宫问题。简单来看一下问题描述,然后直接上代码。

问题描述:

以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。迷宫问题要求求出从入口(1,1)到出口(m,n)的一条通路,或得出没有通路的结论。基本要求:首先实现一个以链表作存储结构的栈类型,然后编写一个求迷宫问题的非递归程序,求得的通路,其中:(x,y)指示迷宫中的一个坐标,dir表示走到下一坐标的方向。左上角(1,1)为入口,右下角(m,n)为出口。

#include <stdio.h>#define SIZE   1024struct Box
{int x;              //点的横坐标int y;              //点的纵坐标int dir;            //下一个点的方向
};
typedef struct Box Box;typedef struct
{Box data[SIZE];int top;
}Stack;//用二位数组表示迷宫,0表示可以走,1表示不可以走
int map[6][6] = { {0, 0, 0, 1, 0, 1}, {0, 1, 0, 0, 1, 0}, {0, 0, 1, 0, 0, 0}, {0, 1, 0, 1, 1, 0}, {0, 1, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0}};//初始化顺序栈
int InitStack(Stack *s)
{if (!s)return -1; s->top = -1;return 0;
}//检查该点是否可以走,1表示不能走,超出地图也不能走
int check(Box b)
{if (b.x < 0 || b.x > 5 || b.y < 0 || b.y > 5)   //点不在迷宫内return -1;if (map[b.x][b.y] != 0)                         //点不能走return -1;return 1;
}//进栈操作
int push(Stack *s, Box b)
{if (s->top == SIZE - 1 || !s)return -1;s->top++;s->data[s->top] = b;return 0;
}//判断栈是否为空
int EmptyStack(Stack *s)
{if (!s)return -1;return (s->top == -1) ? 1 : 0;
}//获取栈顶元素
int GetTop(Stack *s, Box *b)
{if (!s || s->top == -1)return -1;*b = s->data[s->top];return 0;
}//显示一条可以走得通的路径(路径保存在栈中,遍历栈可以得到路径)
void ShowPath(Stack *s)
{int i;for (i = 0; i <= s->top; i++){printf("(%d %d)", s->data[i].x, s->data[i].y);if (i != s->top){printf("->");}}printf("\n");
}//出栈操作
int pop(Stack *s, Box *b)
{if (!s || s->top == -1)return -1;*b = s->data[s->top];s->top--;return 0;
}//修改栈顶元素,下一个点的位置
int ChangeDir(Stack *s, int dir)
{if (!s || s->top == -1)return -1;s->data[s->top].dir = dir;return 0;
}//x1 y1表示起点   x2,y2表示终点
int Walk(Stack *s, int x1, int y1, int x2, int y2)
{Box now, t;int i, j;now.x = x1;now.y = y1;now.dir = -1;if (check(now) == 1){push(s, now);                  //如果该点可以走,则进栈map[now.x][now.y] = -1;        //表示点走过}while (EmptyStack(s) != 1){GetTop(s, &now);               //获取栈顶的点if (now.x == x2 && now.y == y2)    //栈顶元素就是终点{ShowPath(s);map[now.x][now.y] = 0;         //表示点没走过pop(s, &now);GetTop(s, &now);}else{int k;for (k = now.dir + 1; k < 4; k++)        //判断每个方向是否可走{switch(k){case 0:                //向上走i = now.x - 1;j = now.y;break;case 1:i = now.x;j = now.y + 1;break;case 2:               //向下i = now.x + 1;j = now.y;break;case 3:              //向左i = now.x;j = now.y - 1;break;}t.x = i;t.y = j;t.dir = -1;if (check(t) == 1){ChangeDir(s, k);push(s, t);map[i][j] = -1;break;}}if (k == 4)    //没有方向可以走{pop(s, &now);    //无路可走,出栈map[now.x][now.y] = 0;}}}
}int main()
{Stack stack;InitStack(&stack);Walk(&stack, 0, 0, 5, 5);return 0;
}

DFS也是比较符合人的正常思维的算法,沿着一条路一直走下去,发现行不通了再回来,寻找下一个出路。比如上面的迷宫问题其实就是这样解决的。当然如果我们用递归算法也能解决,思想都是一样的。大家再平时的学习过程中也要多去积累一些案例,当你看到一个面试题的时候,如果能够立马想到这个问题用DFS来解决,那题目就会变得非常简单,但是如果你想不到,用自己的办法解决,那就会麻烦的多。

赶紧把上面的代码敲一遍吧!

更多精彩视频、文章、嵌入式学习资料,微信关注公众号 『学益得智能硬件』

如何用栈实现深度优先算法-C语言解决迷宫问题相关推荐

  1. C语言通路寻找,用C语言解决迷宫问题设计与寻找通路问题.pdf

    用c语言解决迷宫设计与寻找通路问题 摘 要:本课程设计主要解决设计一个迷宫以及在给出一组入口和出口的情况下,求出一条通路的问题.在课程 设计中,程序设计语言采用VisualC++6.0,数据结构采用顺 ...

  2. 动画演示深度优先算法搜寻逃出迷宫的路径

    深度优先算法(DFS 算法)是什么? 寻找起始节点与目标节点之间路径的算法,常用于搜索逃出迷宫的路径.主要思想是,从入口开始,依次搜寻周围可能的节点坐标,但不会重复经过同一个节点,且不能通过障碍节点. ...

  3. 教小学妹学算法:搜索算法解决迷宫问题

    Hello,我是 Alex 007,一个热爱计算机编程和硬件设计的小白,为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了. 最近有一位小学妹 Coco 入 ...

  4. 蚂蚁算法C语言解决,蚂蚁优化算法在解决CVRP中的应用

    摘要: According to the disadvantage of basic ant swarm optimization algorithm such weak convergence an ...

  5. 用C语言解决迷宫问题

    迷宫问题是栈这一块很经典的问题. 迷宫大致可分为三种,简单迷宫.多通路迷宫:通路间不带环.多通路迷宫:通路间带环,其中带环多通路迷宫是最复杂的,解决它,要把栈与递归结合起来,下来我们来一个一个分析吧, ...

  6. 深度优先搜索算法在RPG游戏迷宫中的应用

    在RPG游戏中我们经常会看到一些迷宫,我之前玩仙剑一的时候就经常在几个迷宫里绕来绕去也绕不出来,玩仙三由于游戏视角可以转,更是费劲.这里我们使用深度优先算法达到遍历一个迷宫的目的. 首先定义一个有序元 ...

  7. C语言实现一个走迷宫小游戏(深度优先算法)

    补充一下,先前文章末尾给出的下载链接的完整代码含有部分C++的语法(使用Dev-C++并且文件扩展名为.cpp的没有影响),如果有的朋友使用的语言标准是VC6的话可能不支持,所以在修改过后再上传一版, ...

  8. 数据结构_dfs深度优先算法入门(C语言)

    数据结构_dfs深度优先算法入门(C语言) 文章目录 数据结构_dfs深度优先算法入门(C语言) 0.闲话 1.个人理解 2.全排列问题(1到n的排列组合) 2.八皇后问题求解 3.二维迷宫 (1)只 ...

  9. 手动搜索迷宫游戏 c语言,C语言实现一个走迷宫小游戏(深度优先算法)

    接上一篇万年历博文,还是那位朋友的练习题.这次是使用C语言做一个小游戏程序,三选一(2048.8皇后和迷宫游戏),我选择的是迷宫(文章末尾有程序截图).个人认为这个程序的难点在于迷宫地图的绘制,也就是 ...

最新文章

  1. Windows Server下DB2自动备份、复原和前滚的脚本编程
  2. GitHub Copilot 支持 IntelliJ IDEA啦,插件装起来!
  3. postgresql 9.1 暂停 stream 后使用 rsync 异机同步文件
  4. 物联网无线数传通信模块:工业级高精度电源模块
  5. orcale 基本查询(1)
  6. 计算机网络的ip分配,IP地址分配_网络设备技术应用_太平洋电脑网PConline
  7. 25 个精美的后台管理界面模板和布局
  8. AngularJs-指令和指令之间的交互(动感超人)
  9. 如何在MySQL中创建新用户并授予权限
  10. Java Web前后端分离的思考与实践
  11. 2023年厦门大学全日制会计专硕(MPAcc)考研上岸前辈备考经验
  12. 百度开源的 71 个炸天项目
  13. 如何开启win10自带的五笔输入法,并把字库切换成五笔98版
  14. 缠中说禅 教你炒股票 全集列表
  15. 命令行解析模块 以及 metavar 和dest的理解
  16. 32位系统和64位区别
  17. office的加载项作用
  18. 【计算机网络】湖南科技大学 笔记一
  19. Excel学习笔记:P3-冻结窗口与分割视窗
  20. 通过四个多月的时间,我成为了CSDN博客专家

热门文章

  1. gitee创建仓库以及远程连接
  2. 教授夫妻,4年发表7篇Nature!
  3. TX Text Control.NET 14破解
  4. garch模型python步骤_Python中GARCH的预测
  5. R语言计算两个向量的乘法(两个向量的元素依次相乘)
  6. 使用三次多项式拟合天猫双十一交易额
  7. H5中<img>的srcset、size属性及<picture>介绍
  8. 2019,UI革命,暗黑模式的崛起
  9. html5怎么画机器猫,不用HTML5/CSS3如何在网页上画机器猫
  10. 游戏与管理-工人物语2攻略