关闭

数据结构 — 迷宫问题

标签: 迷宫问题C++概念数据结构
788人阅读 评论(4) 收藏 举报
分类:

迷宫问题

_____________________________________________


问题描述:给定一个二维数组如下所示,数值1位墙壁,0为可以走的通路,要求找到出口位置,并且找到最短的路径.

int arr[10][10] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1
};




解决思想:

其实突然拿到该题真的无处下手,我们首先找到最短路径的时候首先就要走完通向出口的每一条路,但是我们走过的路

怎么样才能退回来呢?? 这个时候我们就要用试探法和回溯法合并使用了. 具体如何使用呢?? 来看下面这个图.




具体思想有了,然后现在呢我们思考一些细节的问题. 

首先我们怎么样避免走回头路呢? 这个很容易想到就是对你走过的路程做一个标记. 然后每走一次将这个位置的数值置为

所走的步数,以后试探的时候,只需要判断下一个节点是否为0,或者它的数值是否大于自己,如果大于自己那么就继续走,

如果小于自己的值那么那个节点一定会是回头路. 所以这样的方法可以解决如下这种问题:

int arr[10][10] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1
};

大致思想已经明白了,最重要的代码实现如下:


代码实现:

#include<iostream>
#include<Windows.h>
#include<assert.h>
#include<stack>
using namespace std;


struct pos
{
	pos(int i,int j)
		:row(i)
		,col(j)
	{}

	int col;
	int row;
};

template<int M,int  N>
class maze
{
public:
	maze(int array[M][N])
	{
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < N; j++)
			{
				arr[i][j] = array[i][j];
			}
		}
	}
	maze(const maze& T)
	{
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < N; j++)
			{
				arr[i][j] = T.arr[i][j];
			}
		}
	}
	void printminmazepath()
	{
		pos cur(0,0);
		cout << "出口:";
		while (!q.empty())
		{
			cur = q.top();
			cout<<" < - " << "[" << cur.row << "," << cur.col << "]";
			q.pop();
		}

	}
	void getmazepath(pos enter,int count)
	{
		pos cur = enter;
		pos next = cur;
		arr[enter.row][enter.col] = count+1;
		p.push(cur);

		if (cur.row == N - 1)
		{
			if (q.empty() || q.size() > p.size())
			{
				cout << "找到一个出口为" << "[" << cur.row << "," << cur.col << "]" << endl;;
				q = p;
			}
			cout << endl;
		}
		//向上试探
		next.row -= 1;
		if (CheckAccess(cur, next))
		{
			getmazepath(next, arr[cur.row][cur.col]);
		}

		//向右试探
		next = cur;
		next.col += 1;
		if (CheckAccess(cur, next))
		{
			getmazepath(next, arr[cur.row][cur.col]);
		}

		//向下试探
		next = cur;
		next.row += 1;
		if (CheckAccess(cur, next))
		{
			getmazepath(next, arr[cur.row][cur.col]);
		}

		//向左试探
		next = cur;
		next.col -= 1;
		if (CheckAccess(cur, next))
		{
			getmazepath(next, arr[cur.row][cur.col]);
		}
		p.pop();
		return;
	}

	bool CheckAccess(pos cur,pos next)
	{
		if ((next.row >= 0 && next.row < M)
			&& (next.col >= 0 && next.col <= N)
			&& (arr[next.row][next.col] == 0 || arr[cur.row][cur.col] < arr[next.row][next.col]))
		{
			return true;
		}
		return false;
	}
	void print()
	{
		cout << "该迷宫的俯视图如下->" << endl;
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < N; j++)
			{
				cout << arr[i][j] << "  ";
			}
			cout << endl;
		}
	}
	

private:
	int arr[M][N];
	stack<pos> p;
	stack<pos> q;
};

void Test()
{
	int arr[10][10] =
	{
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
		1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
		1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
		1, 1, 1, 0, 0, 0, 0, 0, 0, 1,
		1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 0, 1, 1, 1, 1
	};

	maze<10,10> arr1(arr);
	arr1.print();
 	arr1.getmazepath(pos(2,0),1);
	arr1.print();
	arr1.printminmazepath();
	system("pause");
}

运行结果:






2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:73290次
    • 积分:2232
    • 等级:
    • 排名:第18992名
    • 原创:135篇
    • 转载:17篇
    • 译文:0篇
    • 评论:72条
    最新评论