C++ 迷宫问题 多条路径 所有路径 最短路径 课程设计

为期一周的数据结构课程设计中写了一个迷宫问题的C++程序,虽然迷宫问题的程序已经很多人贴出来过了,程序也非常地简单,但是只要查过一遍就能发现大多数都是简单的深度优先搜索求一条路径,或者是广度优先搜索遍历求最短路径,之所以很少有求迷宫入口到出口之间所有路径的程序,是因为这样做本身就显得没有必要。若是设计一个走迷宫的小游戏,只要验证玩家给出的路径是否能走通就可以了,若有多条路径可以直接用广度优先搜索来给出最短路径作为答案
但是为了课程设计能得到更高的分数,所以另辟蹊径,先求出入口到出口之间的所有路径,再从所有路径中比较得出最短路径。两点之间求多条路径的程序也不是没有过,没错,就是借鉴图结构两点之间求多条路径的方法,主要思想是利用栈和深度优先搜索

以下是求解的迷宫图:
C++ 迷宫问题 多条路径 所有路径 最短路径 课程设计_第1张图片
详细设计框架:
结构体MapPoint设计:设置两个整形数据成员x和y来表示迷宫中某个点的坐标,成员函数MapPoint way(int direct)根据传入的数字0-7返回相对于当前坐标八个不同方向的点
栈Stack设计:

  1. 数据成员:整型栈顶指针top,minitop和MapPoint类型数组s[80],minipath[80]
  2. 成员函数:
    (1) 构造函数Stack():令top等于-1,构造空栈
    (2) 判空函数bool IsEmpty():栈空返回1,非空返回0
    (3) 入栈函数bool push(MapPoint a):栈非满则将传入的实参存储到数组中
    (4) 出栈函数bool pop():栈非空则出栈
    (5) 取栈顶元素函数MapPoint GetTop():栈非空则返回栈顶元素,栈空则返回起点坐标
    (6) 输出栈函数void Display():若当前栈长度比最小路径数组小,则将当前栈复制给最短路径数组。然后从栈尾开始依次输出栈元素
    (7) 最短路径输出函数bool Shortest():有最短路径则输出最短路径

类Maze设计:

  1. 数据成员been[8][10],MazeMap[8][10]
  2. 成员函数:
    (1) 构造函数Maze():用来初始化数据成员,been全部元素置0,MazeMap中输入迷宫地图
    (2) 地图输出函数void MazeOutput():将迷宫地图以适当格式输出:
    (3) 函数bool Pass(MapPoint p) :判断传入的点是否能走。如果x或y的坐标超出地图范围,或是该点被标记已经走过,或是地图上该点被标记为障碍,都表明该点不可走,随即返回0,否则才返回1
    (4) 寻找并输出所有路径和最短路径的函数void MultiPath(MapPoint Out, Stack &a):用来寻找入口和出口间的所有路径,然后输出最短路径
    (5)用户交互函数void Interact():先输出迷宫地图,然后循环询问用户是否要获得迷宫某两点之间的所有路径和最短路径,根据用户输入来决定是否退出程序。若继续程序,让用户输入出入口坐标,将入口标记和入栈后调用MultiPath()函数来寻找和输出所有路径和最短路径

源代码:
头文件 标头.h:

//Maze.h
#include
using namespace std;

#define MAX 80

struct  MapPoint{			//迷宫点结构体,栈元素类型
	int x;
	int y;
	MapPoint move(int direct);	分别返回相对于当前位置八个方向的点
};

MapPoint MapPoint::move(int direct)		
{
	switch (direct)
	{
	case 0://上
	{
		MapPoint t = { x,y + 1 };
		return t;
	}
	case 1://下
	{
		MapPoint t = { x,y - 1 };
		return t;
	}
	case 2://左
	{
		MapPoint t = { x - 1,y };
		return t;
	}
	case 3://右
	{
		MapPoint t = { x + 1,y };
		return t;
	}
	case 4://左上
	{
		MapPoint t = { x - 1,y + 1 };
		return t;
	}
	case 5://左下
	{
		MapPoint t = { x - 1,y - 1 };
		return t;
	}
	case 6://右上
	{
		MapPoint t = { x + 1,y + 1 };
		return t;
	}
	case 7://右下
	{
		MapPoint t = { x + 1,y - 1 };
		return t;
	}
	default:
		cout << endl << "输入选项错误!";
	}
}

class Stack {				//栈定义
	int top;
	MapPoint s[MAX];
	int minitop;
	MapPoint minipath[MAX];

public:
	Stack()							//空栈构造函数
	{top = -1; minitop = MAX - 1;}

	bool IsEmpty() {				//栈空判定
		if (top == -1) 
			return 1;
		else 
			return 0;
	}

	bool push(MapPoint a) {			//入栈
		if (top == MAX - 1)
		{
			cout << endl << "栈已满!";
			return 0;
		}
		else {
			top++;
			s[top].x = a.x;
			s[top].y = a.y;
			return 1;
		}
	}

	bool pop() {				//出栈
		if (IsEmpty()) { return 0; }
		else { top--; return 1; }
	}

	MapPoint GetTop() {					//取栈顶元素
		if (top != -1)
			return s[top];
		else							//栈空则返回起点的坐标
		{
			MapPoint t;
			t.x = 1; t.y = 1;
			return t;
		}
	}

	void Display() {							//从栈尾依次输出栈元素,即输出迷宫通路
		if (minitop > top)						//每次输出路径前尝试修改保存的最短路径
		{
			minitop = top;
			for (int i = 0; i <= top; i++)
				minipath[i] = s[i]; 
		}

		cout << endl;
		cout << endl << "找到路径如下:";
		for (int i = 0; i<=top; i++)
		{
			cout << '(' << s[i].x << "," << s[i].y << ')';
			if (i != top)
				cout << "->";
		}
	}

	bool Shortest()				//输出最短路径
	{
		cout << endl;
		if (minitop == MAX - 1)
		{
			cout << endl << "找不到入口与出口间的通路,故无最短路径!";
			return 0;
		}
		else
		{
			cout << endl << "最短路径如下:";
			for (int i = 0; i <= minitop; i++)
			{
				cout << '(' << minipath[i].x << "," << minipath[i].y << ')';
				if (i != minitop)
					cout << "->";
			}
			minitop = MAX - 1;			//输出一遍后重置
			return 1;
		}
	}
};

class Maze {
	int been[8][10];			//用做标记走过的点
	int MazeMap[8][10];			//迷宫地图定义
public:
	Maze();														//构造函数
	bool Pass(MapPoint p);										//判断某点是否可以走
	void MultiPath(MapPoint Out, Stack &a);						//寻找和输出所有路径和标出最短路径
	void MazeOutput();											//输出迷宫地图
	void Interact();											//用户交互函数
};

Maze::Maze()						//所有标志置0,定义迷宫地图 
{
	int i, j;
	for (i = 0; i < 8; i++)
		for (j = 0; j < 10; j++)
			been[i][j] = 0;
	int map[8][10]={
	{ 1,1,1,1,1,1,1,1,1,1 },
	{ 1,0,1,1,1,0,1,1,1,1 },
	{ 1,1,0,1,0,1,1,1,1,1 },
	{ 1,0,1,0,0,0,0,0,1,1 },
	{ 1,0,1,1,1,0,1,1,1,1 },
	{ 1,1,0,0,1,1,0,0,0,1 },
	{ 1,0,1,1,0,0,1,1,0,1 },
	{ 1,1,1,1,1,1,1,1,1,1 }
	};
	for (i = 0; i < 8; i++)
		for (j = 0; j < 10; j++)
			MazeMap[i][j] = map[i][j];
}

bool Maze::Pass(MapPoint p) {			//成员函数pass定义
	if (p.x<0 || p.x>7) {		 //x坐标超出迷宫范围
		return 0;
	}
	else if (p.y<0 || p.y>9) {	 //y坐标超出迷宫范围
		return 0;
	}
	else if (been[p.x][p.y] == 1) {//前面已经走过该点
		return 0;
	}
	else if (MazeMap[p.x][p.y] == 1){//该点是障碍
		return 0;
	}
	else return 1;			 //可以走
}

void Maze::MultiPath(MapPoint Out, Stack &a)	//成员函数MultiPath定义
{
	MapPoint l = a.GetTop();
	if (l.x == Out.x&&l.y == Out.y) {			//栈顶元素为出口则输出当前路径
		a.Display();							//后回退(取标出栈)并结束函数调用
		been[l.x][l.y] = 0;
		a.pop();
		return;
	}

	for (int i = 0; i < 8; i++)					//循环遍历探测周围方向上的点
	{											//保证递归返回到分叉点时不再选择已选方向
		if (Pass(l.move(i)))
		{
			MapPoint m = l.move(i); 
			been[m.x][m.y] = 1;
			a.push(m);

			MultiPath(Out, a);
		}
	}
	if (a.pop())								//该分叉点已探测完所有选项,出栈成功则取标回退
		been[l.x][l.y] = 0;
	if (a.IsEmpty())
		if(a.Shortest())
			cout << endl << "所有路径及最短路径输出完毕!";	   //栈空表明再无分支
}

void Maze::MazeOutput()							//成员函数MazeOutput定义
{
	cout << "迷宫图如下:" << endl;
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			cout << MazeMap[i][j] << " ";
		}
		cout << endl;
	}
}

void Maze::Interact()							//成员函数interact定义
{
	char answer;
	MapPoint Out, In;		//定义出口和人口
	Stack a;

	MazeOutput();

	while (true)
	{
		cout << endl << "你想知道该迷宫某两点之间的所有路径和最短路径吗?";
		cout << endl << "回答是或否(输入Y/N),输入迷宫入口和出口获悉路径或退出程序:";
		cin >> answer;
		if (answer == 'Y' || answer == 'y')			//MultiPath调用完后所有标记由于回退会被清除
		{
			cout << endl << "请输入入口坐标:";
			cin >> In.x >> In.y;
			cout << endl << "请输入出口坐标:";
			cin >> Out.x >> Out.y;
			been[In.x][In.y] = 1;
			a.push(In);				//将入口入栈
			MultiPath(Out, a);
			cout << endl;
		}
		else if (answer == 'N' || answer == 'n')
			break;
		else
			cout << endl << "输入数据无效,请重新输入有效数据回答该问题!";
	}
}

源文件 源.cpp :

//Maze.cpp
#include"标头.h"

int main()
{		
	Maze m;
	m.Interact();
	
	system("pause");
	return 0;
}

设计特色:先求所有路径,再比较得出最短路径;地图存储在二维数组内,不必手动输入,运行直接显示全地图;将迷宫及其操作函数整合为一个类,模块化编程

详细课程设计报告链接:https://wenku.baidu.com/view/89cae68bf605cc1755270722192e453610665bde

你可能感兴趣的:(C++ 迷宫问题 多条路径 所有路径 最短路径 课程设计)