<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="http://gentoo-zh.org/extern.php?action=feed&amp;tid=611&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Gentoo中文社区 / 迷宫寻址中深度优先搜索的递归和非递归算法比较]]></title>
		<link>http://www.gentoo-zh.org/viewtopic.php?id=611</link>
		<description><![CDATA[迷宫寻址中深度优先搜索的递归和非递归算法比较 最近发表的帖子。]]></description>
		<lastBuildDate>Fri, 09 Dec 2022 09:00:45 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[迷宫寻址中深度优先搜索的递归和非递归算法比较]]></title>
			<link>http://www.gentoo-zh.org/viewtopic.php?pid=654#p654</link>
			<description><![CDATA[<p>迷宫寻址中深度优先搜索的递归和非递归算法比较</p><p>&#160; &#160; 巧若拙（欢迎转载，但请注明出处：http://blog.csdn.net/qiaoruozhuo）</p><p>&#160; &#160; 本文只探究迷宫寻址中深度优先搜索的递归和非递归算法比较，其他相关代码详见《迷宫问题（巧若拙）》http://blog.csdn.net/qiaoruozhuo/article/details/41020745</p><p>&#160; &#160; 深度优先搜索的递归算法是很容易实现的，只需设置一个驱动函数，然后递归调用子函数就可以了。<br />代码如下：<br />int DeepSearchWay()//寻找路径：深度搜索<br />{<br />&#160; &#160; CopyMiGong();<br />&#160; &#160; &#160; <br />&#160; &#160; if (c_map[begin[0]][begin[1]] == OPEN &amp;&amp; Search(begin[0], begin[1]))<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; c_map[begin[0]][begin[1]] = ROAD;<br />&#160; &#160; &#160; &#160; return true;<br />&#160; &#160; }<br />&#160; &#160; &#160; &#160; <br />&#160; &#160; return false;<br />}</p><p>int Search(int x, int y)//深度搜索递归子函数<br />{<br />&#160; &#160; int i;</p><p>&#160; &#160; &#160; &#160;c_map[x][y] = PASSED;&#160; <br />&#160; &#160; if (IsEnd(x, y)) //找到出口<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; c_map[x][y] = ROAD;&#160; <br />&#160; &#160; &#160; &#160; return true;<br />&#160; &#160; }<br />&#160; &#160; &#160; <br />&#160; &#160; for (i=0; i&lt;4; i++)//判断当前路径点四周是否可通过<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; if (c_map[x+zx[ i]][y+zy[i ]] == OPEN &amp;&amp; Search(x+zx[i ], y+zy[i ]))<br />&#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; c_map[x][y] = ROAD;<br />&#160; &#160; &#160; &#160; &#160; &#160; return true;<br />&#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160;}<br />&#160; &#160;return false;<br />}</p><br /><br /><p>深度优先搜索的非递归算法需要人工设置一个栈，把搜索过的点存储到栈中，走不通的点就退栈，找到出口就退出函数。<br />代码如下：<br />int DeepSearchWay_2()//寻找路径：深度搜索<br />{<br />&#160; &#160; int x, y;<br />&#160; &#160; int top = 0; //栈顶指针<br />&#160; &#160; int sum = 0;//累积搜索过的点数量</p><p>&#160; &#160; CopyMiGong();<br />&#160; &#160; way[0].x = begin[0];<br />&#160; &#160; way[0].y = begin[1];<br />&#160; &#160; way[0].pre = 0;<br />&#160; &#160; c_map[way[0].x][way[0].y] = PASSED; //该点已走过</p><p>&#160; &#160; while (top &gt;= 0)<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; if (way[top].pre &lt; 4)<br />&#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; x = way[top].x + zx[way[top].pre];<br />&#160; &#160; &#160; &#160; &#160; &#160; y = way[top].y + zy[way[top].pre];</p><p>&#160; &#160; &#160; &#160; &#160; &#160; if (c_map[x][y] == OPEN)//如果某个方向可通过，将该点纳入栈<br />&#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; sum++;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; top++;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].x = x;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].y = y;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].pre = 0;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; c_map[x][y] = PASSED;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (IsEnd(x, y)) //找到出口<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; PutStack(top); //把栈路径显示到迷宫中<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; printf(&quot;\n深度优先搜索可行路径，总共搜索过%d个点\n&quot;, sum);<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; return true;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; &#160; &#160; else&#160; //否则换个方向<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].pre++;<br />&#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; else<br />&#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;top--;<br />&#160; &#160; &#160; &#160; &#160; &#160;}<br />&#160; &#160; }<br />&#160; &#160; return false;<br />}</p><p>void PutStack(int top) //把栈路径显示到迷宫中<br />{<br />&#160; &#160; CopyMiGong();</p><p>&#160; &#160; &#160; &#160;while (top &gt;= 0)<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; c_map[way[top].x][way[top].y] = ROAD;<br />&#160; &#160; &#160; &#160; top--;<br />&#160; &#160; }<br />}</p><p>深度优先搜索最短路径，除了存储当前遍历结点的栈以外，需要额外设置一个栈存储最短路径。为了避免重复搜索某顶点，我为各个顶点设置了路径长度，只有当前路径长度小于原来的路径长度时，才搜索该顶点。<br />找到出口后并不退出函数，若当前路径长度小于最小路径长度，则更新最小路径长度，否则直接退栈进入上一点，继续搜索。<br />直到所有可能的路径被搜索完毕，输出最短路径。<br />代码如下：<br />int DeepSearchWay_3()//寻找路径：深度搜索（最短路径）<br />{<br />&#160; &#160; int x, y, i, j;<br />&#160; &#160; int top = 0; //栈顶指针<br />&#160; &#160; int pathLen[M+2][N+2] = {0};<br />&#160; &#160; struct stype shortWay[M*N];<br />&#160; &#160; int flag = false; //标记是否能到达终点&#160; <br />&#160; &#160; int sum = 0;//累积搜索过的点数量<br />&#160; &#160;<br />&#160; &#160; for (x=0; x&lt;M+2; x++) //设置各点初始路径长度均为最大值<br />&#160; &#160; &#160; &#160; for (y=0; y&lt;N+2; y++)<br />&#160; &#160; &#160; &#160; &#160; &#160; pathLen[x][y] = MAXLEN;</p><p>&#160; &#160; CopyMiGong();<br />&#160; &#160; minLen = MAXLEN;&#160; //最短路径<br />&#160; &#160; way[0].x = begin[0];<br />&#160; &#160; way[0].y = begin[1];<br />&#160; &#160; way[0].pre = 0;<br />&#160; &#160; pathLen[begin[0]][begin[1]] = 0;</p><p>&#160; &#160; while (top &gt;= 0)<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; if (way[top].pre &lt; 4)<br />&#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; x = way[top].x + zx[way[top].pre];<br />&#160; &#160; &#160; &#160; &#160; &#160; y = way[top].y + zy[way[top].pre];</p><p>&#160; &#160; &#160; &#160; &#160; &#160; if (c_map[x][y] == OPEN &amp;&amp; pathLen[x][y] &gt; top+1)//如果某个方向可通过，且为最短路径，将该点纳入栈<br />&#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; sum++;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; top++;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].x = x;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].y = y;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].pre = 0;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; pathLen[x][y] = top;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (IsEnd(x, y)) //找到出口<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (top &lt; minLen)<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; minLen = top;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; for (i=0; i&lt;=top; i++)<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; shortWay[i ] = way[i ];<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }</p><p>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; flag = true;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; top--;<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; &#160; &#160; else&#160; //否则换个方向<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; way[top].pre++;<br />&#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; else<br />&#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;top--;<br />&#160; &#160; &#160; &#160; &#160; &#160;}<br />&#160; &#160; }<br />&#160; &#160;<br />&#160; &#160; if (flag)<br />&#160; &#160; {<br />&#160; &#160; &#160; &#160; for (i=0; i&lt;=minLen; i++)<br />&#160; &#160; &#160; &#160; {<br />&#160; &#160; &#160; &#160; &#160; &#160; way[i ] = shortWay[i ];<br />&#160; &#160; &#160; &#160; }<br />&#160; &#160; &#160; &#160; PutStack(minLen); //把栈路径显示到迷宫中<br />&#160; &#160; }<br />&#160; &#160;<br />&#160; &#160; printf(&quot;\n深度优先搜索最短路径，总共搜索过%d个点\n&quot;, sum);<br />&#160; &#160; &#160; &#160; <br />&#160; &#160; return flag;<br />}</p>]]></description>
			<author><![CDATA[dummy@example.com (batsom)]]></author>
			<pubDate>Fri, 09 Dec 2022 09:00:45 +0000</pubDate>
			<guid>http://www.gentoo-zh.org/viewtopic.php?pid=654#p654</guid>
		</item>
	</channel>
</rss>
