1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define ROW 10
  5. #define COL 10
  6.  
  7. /*迷宫中位置信息*/
  8. typedef struct position
  9. {
  10. int x;
  11. int y;
  12. }position;
  13.  
  14. /*在迷宫中的当前位置的信息,也是入栈的基本元素*/
  15. typedef struct SElem
  16. {
  17. int di;
  18. position seat;
  19. }SElem;
  20.  
  21. /*链式栈中节点的定义*/
  22. typedef struct position_stack
  23. {
  24. SElem p;
  25. struct position_stack *next;
  26. }*Stack_pNode,Stack_Node;
  27.  
  28. void InitStack(Stack_pNode *Link)
  29. {
  30. *Link = NULL;
  31. }
  32.  
  33. void push(Stack_pNode *Link,SElem e)
  34. {
  35. Stack_pNode new_SElem = (Stack_pNode)calloc(1,sizeof(Stack_Node));
  36. new_SElem->p = e;
  37. new_SElem->next = NULL;
  38. if (*Link == NULL)
  39. *Link = new_SElem;
  40. else
  41. {
  42. new_SElem->next = *Link;
  43. *Link = new_SElem;
  44. }
  45. }
  46.  
  47. int pop(Stack_pNode *Link,SElem *e)
  48. {
  49. if (*Link == NULL)
  50. return 0;
  51. *e = (*Link)->p;
  52. Stack_pNode q = *Link;
  53. *Link = (*Link)->next;
  54. free(q);
  55. return 1;
  56. }
  57.  
  58. int top(Stack_pNode Link, SElem *e)
  59. {
  60. if (Link == NULL)
  61. return 0;
  62. *e = Link->p;
  63. return 1;
  64. }
  65.  
  66. int empty(Stack_pNode Link)
  67. {
  68. if (Link == NULL)
  69. return 1;
  70. else
  71. return 0;
  72. }
  73.  
  74. int reverse(Stack_pNode *Link)
  75. {
  76. Stack_pNode p, q, r;
  77. if (*Link == NULL || (*Link)->next == NULL)
  78. return 0;
  79. r = *Link;
  80. p = (*Link)->next;
  81. q = NULL;
  82. while (p){
  83. r->next = q;
  84. q = r;
  85. r = p;
  86. p = p->next;
  87. }
  88. r->next = q;
  89. *Link = r;
  90. }
  91.  
  92. void print(Stack_pNode Link)
  93. {
  94. Stack_pNode r = Link;
  95. while (r){
  96. printf("(%d,%d) -> ",r->p.seat.x,r->p.seat.y);
  97. r = r->next;
  98. }
  99. printf("exit\n");
  100. }
  101.  
  102. int curstep = 1;/*纪录当前的足迹,填写在探索前进的每一步正确的路上*/
  103. /*迷宫地图。1代表墙的位置,0代表可行的路,周围有一圈墙*/
  104. int m[ROW+2][COL+2] = {
  105. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  106. 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
  107. 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,
  108. 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1,
  109. 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1,
  110. 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,
  111. 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1,
  112. 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
  113. 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1,
  114. 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
  115. 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,
  116. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
  117. };
  118. /*方向优先级设定。依次为当前位置的右,下,左。上,在位置信息中。保存有本次
  119.  
  120. 前进的方向--数组的下标*/
  121. position dir_set[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
  122.  
  123. /*推断当前位置是否可行。即推断是路。还是墙*/
  124. int pass(position p)
  125. {
  126. if (m[p.x][p.y])
  127. return 0;
  128. else
  129. return 1;
  130. }
  131. /*将当前的步数填写在走的每一步正确的路上,当发现走不通时,会把当时写的信息
  132.  
  133. 用‘1’抹掉,代表走不通。
  134.  
  135. */
  136. void footPrint(position p)
  137. {
  138. m[p.x][p.y] = curstep;
  139. }
  140. /*计算下一步的坐标。di代表方向。本函数仅仅负责计算下一步坐标。不推断优先级*/
  141. void nextPos(position *p, int di)
  142. {
  143. (*p).x += dir_set[di].x;
  144. (*p).y += dir_set[di].y;
  145. }
  146. /*如上面的footPrint()凝视中提到的,当发现当前路走不通时,会用‘1’把走不通的
  147.  
  148. 路堵上。
  149.  
  150. */
  151. void markPrint(position p)
  152. {
  153. m[p.x][p.y] = 1;
  154. }
  155. /*迷宫程序的主函数。形參是一个指向不带头节点的栈的指针的指针,一个開始位置
  156.  
  157. ,一个结束位置*/
  158. int find_path(Stack_pNode * Maze_stack,position start,position end)
  159. {
  160. position curpos = start;/*定义一个位置变量。用来保存当前的位置信息
  161.  
  162. */
  163. SElem e;/*栈的元素。包含位置信息,和前进的方向*/
  164. do
  165. {
  166. if (pass(curpos)){ /*假设当前节点是路,则要将当前节点入栈。
  167.  
  168. 并计算下一步前进方向*/
  169. footPrint(curpos);/*在前进节点上纪录当前的步数*/
  170. e.seat = curpos;/*保存位置信息*/
  171. e.di = 0;/*保存方向信息。默觉得向右*/
  172. push(Maze_stack, e);/*将位置信息入栈*/
  173. ++curstep;/*步数加1*/
  174. if (curpos.x == end.x && curpos.y == end.y)/*假设当
  175.  
  176. 前节点是出口。则返回运行成功的标识*/
  177. return 1;
  178. nextPos(&curpos, e.di);/*计算下一步的坐标。是依据当
  179.  
  180. 前位置信息计算的,即已经入栈了的信息*/
  181. }
  182. else{/*假设当前节点是墙。则须要从栈取出之前走过的路,即沿原
  183.  
  184. 路返回,在返回的过程中,还要不断的推断有没有其它的路*/
  185. if (!empty(*Maze_stack)){/*假设栈中有元素*/
  186. pop(Maze_stack,&e);
  187. --curstep;
  188. while (e.di == 3 && !empty(*Maze_stack)){/*
  189.  
  190. 边向前回溯,边推断是否有其它的路可走*/
  191. markPrint(e.seat);/*用"墙"覆盖之前
  192.  
  193. 填写的步数信息*/
  194. pop(Maze_stack,&e);
  195. --curstep;
  196. }
  197. if (e.di < 3){/*当找到了一个还有其它的路可
  198.  
  199. 走之前走过的一个方块(最坏的情况是回到起始位置)*/
  200. ++e.di;/*按优先级改变之前的行走方向
  201.  
  202. */
  203. push(Maze_stack, e);/*再次入栈*/
  204. ++curstep;/*再次将步数加1*/
  205. curpos = e.seat;/*再次纪录如今的位
  206.  
  207. 置*/
  208. nextPos(&curpos, e.di);/*再次计算下
  209.  
  210. 次的方向,有了以上的准备,即将进行下一次的循环*/
  211. }//end if
  212. }//end if
  213. }//end else
  214. } while (!empty(*Maze_stack));
  215. return 0;
  216. }
  217.  
  218. /*打印迷宫*/
  219. void printMaze()
  220. {
  221. int i, j;
  222. for (i = 0; i < ROW+2; ++i)
  223. {
  224. for (j = 0; j < COL+2; ++j){
  225. printf("%2d ", m[i][j]);
  226. }
  227. printf("\n");
  228. }
  229.  
  230. }
  231.  
  232. int main()
  233. {
  234. //stack_test();
  235. position start = { 1, 1 };/*迷宫入口*/
  236. position end = { 10, 10 };/*迷宫出口*/
  237. Stack_pNode maze_stack;/*声明一个栈,一会儿用来存放在迷宫中走过的位
  238.  
  239. 置*/
  240. InitStack(&maze_stack);/*初始化栈*/
  241. if (find_path(&maze_stack, start, end)){
  242. reverse(&maze_stack);/*因为栈中存放的是倒置的信息,须要将栈
  243.  
  244. 倒置*/
  245. print(maze_stack);/*打印带有走过的步数信息的迷宫地图*/
  246. }
  247. else{
  248. printf("Has no way to out of the maze.\n");
  249. }
  250. printMaze();
  251.  
  252. return 0;
  253. }

用C语言解决迷宫问题的更多相关文章

  1. C语言解决约瑟夫问题详解的代码

    将开发过程中比较重要的一些内容做个收藏,下面的内容是关于C语言解决约瑟夫问题详解的内容,希望能对码农有帮助. #pragma once #include<vector> class PRO ...

  2. 15 GIL 全局解释器锁 C语言解决 top ps

    1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...

  3. 有关dfs、bfs解决迷宫问题的个人见解

    可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是 ...

  4. 关于C语言解决汉诺塔(hanoi)问题

    C语言解决汉诺塔问题 汉诺塔是典型的递归调用问题: hanoi简介:印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣 ...

  5. 应用栈解决迷宫问题的C语言实现

    题目来自于严蔚敏<数据结构>,参考伪代码实现的程序: #include <stdio.h> #include <malloc.h> //记录通道块在迷宫矩阵当中的横 ...

  6. 回溯算法-C#语言解决八皇后问题的写法与优化

    结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解 ...

  7. BFS 、DFS 解决迷宫入门问题

    问题 B: 逃离迷宫二 时间限制: 1 Sec  内存限制: 128 MB提交: 12  解决: 5[提交][状态][讨论版] 题目描述 王子深爱着公主.但是一天,公主被妖怪抓走了,并且被关到了迷宫. ...

  8. 用C语言解决python多线程中的GIL问题

    在使用python多线程的时候为了解决GIL问题,有些代码得用C语言写,那么就得生成动态链接库. 当创建动态链接库时,独立位置信息(position independent)代码也需要生成.这可以帮助 ...

  9. 使用prolog逻辑语言解决爱因斯坦斑马难题

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...

随机推荐

  1. PowerDesigner数据模型(CDM—PDM—SQL脚本的转换流程)

    原文地址:PowerDesigner数据模型(CDM-PDM-SQL脚本的转换流程)作者:zzenglish 有图片的参考http://blog.sina.com.cn/s/blog_64742675 ...

  2. [LeetCode] Sudoku Solver 解数独,递归,回溯

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  3. TCP/IP协议详解笔记——ARP协议和RARP协议

    ARP:地址解析协议 对于以太网,数据链路层上是根据48bit的以太网地址来确定目的接口,设备驱动程序从不检查IP数据报中的目的IP地址.ARP协议为IP地址到对应的硬件地址之间提供动态映射. 工作过 ...

  4. MPchartAndroid-柱状图

    mChart = (LineChart) findViewById(R.id.chart1); mChart.setDescription("");    //设置图表描述信息 m ...

  5. poj 2892(二分+树状数组)

    Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7749   Accepted: 3195 D ...

  6. Android判断是否为刘海屏

    主要总结主流品牌小米.华为.oppo.vivo的刘海屏判断.在某些特殊页面需要适配刘海屏时,可以用以下方法判断.或者判断屏幕比例是否大于2. /** * 小米刘海屏判断. */ public stat ...

  7. js上传Excel文件

    一.问题 需要在项目里添加一个上传excel文件的功能,因为其他同样的后台里面有上传文件的功能,第一反应就是想着直接用.了解了一下发现它是利用bootstrap的fileinput实现的,但是我怎么都 ...

  8. 通用mapper的框架

    这两个框架都是一个大神写的.用来做单表的增删改查,爽爽的. 但是复杂的查询还不知道如何用,所以我还按传统的方式 写 service maperr ,写SQL来处理复杂查询,与多表的查询.  它的复杂查 ...

  9. Java多线程总结之由synchronized说开去

    更新完毕,结贴,以后有新的想法再开新帖 这几天不断添加新内容,给个大概的提纲吧,方面朋友们阅读,各部分是用分割线隔开了的: synchronized与wait()/notify() JMM与synch ...

  10. POJ 3254 Corn Fields [DP]

    题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...