迷宫寻址中深度优先搜索的递归和非递归算法比较

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo

本文只探究迷宫寻址中深度优先搜索的递归和非递归算法比较,其他相关代码详见《迷宫问题(巧若拙)》http://blog.csdn.net/qiaoruozhuo/article/details/41020745

深度优先搜索的递归算法是很容易实现的,只需设置一个驱动函数,然后递归调用子函数就可以了。

代码如下:

int DeepSearchWay()//寻找路径:深度搜索

{

CopyMiGong();

if (c_map[begin[0]][begin[1]] == OPEN && Search(begin[0],begin[1]))

{

c_map[begin[0]][begin[1]] = ROAD;

return true;

}

return false;

}

int Search(int x, int y)//深度搜索递归子函数

{

inti;

c_map[x][y] = PASSED;

if(IsEnd(x, y)) //找到出口

{

c_map[x][y] = ROAD;

return true;

}

for (i=0; i<4; i++)//判断当前路径点四周是否可通过

{

if (c_map[x+zx[i]][y+zy[i]] ==OPEN && Search(x+zx[i], y+zy[i]))

{

c_map[x][y] = ROAD;

return true;

}

}

return false;

}

深度优先搜索的非递归算法需要人工设置一个栈,把搜索过的点存储到栈中,走不通的点就退栈,找到出口就退出函数。

代码如下:

int DeepSearchWay_2()//寻找路径:深度搜索

{

intx, y;

int top = 0; //栈顶指针

int sum = 0;//累积搜索过的点数量

CopyMiGong();

way[0].x = begin[0];

way[0].y = begin[1];

way[0].pre = 0;

c_map[way[0].x][way[0].y] = PASSED; //该点已走过

while (top >= 0)

{

if (way[top].pre < 4)

{

x = way[top].x + zx[way[top].pre];

y = way[top].y + zy[way[top].pre];

if (c_map[x][y] == OPEN)//如果某个方向可通过,将该点纳入栈

{

sum++;

top++;

way[top].x = x;

way[top].y = y;

way[top].pre = 0;

c_map[x][y] = PASSED;

if (IsEnd(x, y)) //找到出口

{

PutStack(top); //把栈路径显示到迷宫中

printf("\n深度优先搜索可行路径,总共搜索过%d个点\n", sum);

return true;

}

}

else  //否则换个方向

way[top].pre++;

}

else

{

top--;

}

}

return false;

}

void PutStack(int top) //把栈路径显示到迷宫中

{

CopyMiGong();

while (top >= 0)

{

c_map[way[top].x][way[top].y] = ROAD;

top--;

}

}

深度优先搜索最短路径,除了存储当前遍历结点的栈以外,需要额外设置一个栈存储最短路径。为了避免重复搜索某顶点,我为各个顶点设置了路径长度,只有当前路径长度小于原来的路径长度时,才搜索该顶点。

找到出口后并不退出函数,若当前路径长度小于最小路径长度,则更新最小路径长度,否则直接退栈进入上一点,继续搜索。

直到所有可能的路径被搜索完毕,输出最短路径。

代码如下:

int DeepSearchWay_3()//寻找路径:深度搜索(最短路径)

{

intx, y, i, j;

int top = 0; //栈顶指针

int pathLen[M+2][N+2] = {0};

struct stype shortWay[M*N];

intflag = false; //标记是否能到达终点

intsum = 0;//累积搜索过的点数量

for (x=0; x<M+2; x++) //设置各点初始路径长度均为最大值

for (y=0; y<N+2; y++)

pathLen[x][y] = MAXLEN;

CopyMiGong();

minLen= MAXLEN;  //最短路径

way[0].x = begin[0];

way[0].y = begin[1];

way[0].pre = 0;

pathLen[begin[0]][begin[1]] = 0;

while (top >= 0)

{

if (way[top].pre < 4)

{

x = way[top].x + zx[way[top].pre];

y = way[top].y + zy[way[top].pre];

if (c_map[x][y] == OPEN && pathLen[x][y] > top+1)//如果某个方向可通过,且为最短路径,将该点纳入栈

{

sum++;

top++;

way[top].x = x;

way[top].y = y;

way[top].pre = 0;

pathLen[x][y] = top;

if (IsEnd(x, y)) //找到出口

{

if(top < minLen)

{

minLen= top;

for(i=0; i<=top; i++)

{

shortWay[i]= way[i];

}

}

flag = true;

top--;

}

}

else  //否则换个方向

way[top].pre++;

}

else

{

top--;

}

}

if (flag)

{

for (i=0; i<=minLen; i++)

{

way[i] = shortWay[i];

}

PutStack(minLen); //把栈路径显示到迷宫中

}

printf("\n深度优先搜索最短路径,总共搜索过%d个点\n", sum);

return flag;

}

时间: 2024-11-02 23:38:08

迷宫寻址中深度优先搜索的递归和非递归算法比较的相关文章

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树的前序、中序、后序遍历的递归和非递归算法实现

1 /** 2 * 二叉树的前序.中序.后序遍历的递归和非递归算法实现 3 **/ 4 5 //二叉链表存储 6 struct BTNode 7 { 8 struct BTNode *LChild; // 指向左孩子指针 9 ELEMENTTYPE data; // 结点数据 10 struct BTNode *RChild; // 指向右孩子指针 11 }; 12 13 /** 14 * 前序遍历 15 **/ 16 // 递归实现 17 void PreorderTraversal(BTNo

二叉树的三种遍历的递归与非递归算法

今天复习了一下二叉树的前序遍历.中序遍历.后序遍历的递归与非递归算法,顺便记录一下: //TreeTest.h #include <iostream> struct TreeNode { int value; TreeNode* leftChild; TreeNode* rightChild; void print() { printf("%d ",value); } }; class MyTree { private: TreeNode* m_root; TreeNode

快速排序(递归及非递归算法源码)

1. 递归算法: quicksort.cpp #include <iostream>using namespace std; void Swap(int a[],int i,int j){ int temp=a[i]; a[i] = a[j]; a[j] = temp;}int Partition(int a[],int low, int high){ int pivot=a[low]; while(low<high) { while(low<high && a[h

二分查找的递归与非递归算法

/* 二分查找的递归与非递归算法 */ #include <iostream> #include <cstdio> using namespace std; bool bisrch( int low,int high,int v,int *text ) //递归写法 { int i,mid; mid=( low+high )/2; if( low>high ) return false; if( v==text[mid] ) return true; else if( v&l

castle problem——(深度优先搜索,递归实现和stack实现)

将问题的各状态之间的转移关系描述为一个图,则深度优先搜索遍历整个图的框架为:Dfs(v) {if( v 访问过)return;将v标记为访问过;对和v相邻的每个点u: Dfs(u);}int main() {while(在图中能找到未访问过的点 k)Dfs(k);} 4例题:百练2815 城堡问题? 右图是一个城堡的地形图.请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大.城堡被分割成m×n(m≤50,n≤50)个方块,每个方块可以有0~4面墙.5输入输出? 输入? 程序从标准输入设备

二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式

二叉树的遍历方式: 1.深度优先:递归,非递归实现方式 1)先序遍历:先访问根节点,再依次访问左子树和右子树 2)中序遍历:先访问左子树,再访问根节点吗,最后访问右子树 3)后序遍历:先访问左子树,再访问右子树,最后访问根节点 2.广度优先     按照树的深度,一层一层的访问树的节点 1 package Solution; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Stack; 6

【数据结构】二叉树(前、中、后)序遍历的递归与非递归算法

对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对 于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一 点. 二叉树前序:访问根节点->左子树->右子树 (1)递归写法: 依次访问根节点.左子树.右子树,注意递归出口的结束. void _PrevOrder(Node* root)     {         i

斐波那契数与二分法的递归与非递归算法及其复杂度分析

1. 什么是斐波那契数? 这里我借用百度百科上的解释:斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就是斐波那契数列列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加.特别指出:0不是第一