用C语言解决迷宫问题

#include <stdio.h>
#include <stdlib.h>

#define ROW 10
#define COL 10

/*迷宫中位置信息*/
typedef struct position
{
	int x;
	int y;
}position;

/*在迷宫中的当前位置的信息,也是入栈的基本元素*/
typedef struct SElem
{
	int di;
	position seat;
}SElem;

/*链式栈中节点的定义*/
typedef struct position_stack
{
	SElem p;
	struct position_stack *next;
}*Stack_pNode,Stack_Node;

void InitStack(Stack_pNode *Link)
{
	*Link = NULL;
}

void push(Stack_pNode *Link,SElem e)
{
	Stack_pNode new_SElem = (Stack_pNode)calloc(1,sizeof(Stack_Node));
	new_SElem->p = e;
	new_SElem->next = NULL;
	if (*Link == NULL)
		*Link = new_SElem;
	else
	{
		new_SElem->next = *Link;
		*Link = new_SElem;
	}
}

int pop(Stack_pNode *Link,SElem *e)
{
	if (*Link == NULL)
		return 0;
	*e = (*Link)->p;
	Stack_pNode q = *Link;
	*Link = (*Link)->next;
	free(q);
	return 1;
}

int top(Stack_pNode Link, SElem *e)
{
	if (Link == NULL)
		return 0;
	*e = Link->p;
	return 1;
}

int empty(Stack_pNode Link)
{
	if (Link == NULL)
		return 1;
	else
		return 0;
}

int reverse(Stack_pNode *Link)
{
	Stack_pNode p, q, r;
	if (*Link == NULL || (*Link)->next == NULL)
		return 0;
	r = *Link;
	p = (*Link)->next;
	q = NULL;
	while (p){
		r->next = q;
		q = r;
		r = p;
		p = p->next;
	}
	r->next = q;
	*Link = r;
}

void print(Stack_pNode Link)
{
	Stack_pNode r = Link;
	while (r){
		printf("(%d,%d) -> ",r->p.seat.x,r->p.seat.y);
		r = r->next;
	}
	printf("exit\n");
}

int curstep = 1;/*纪录当前的足迹,填写在探索前进的每一步正确的路上*/
/*迷宫地图。1代表墙的位置,0代表可行的路,周围有一圈墙*/
int m[ROW+2][COL+2] = {
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
	1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,
	1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1,
	1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1,
	1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,
	1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1,
	1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
	1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1,
	1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
	1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
/*方向优先级设定。依次为当前位置的右,下,左。上,在位置信息中。保存有本次

前进的方向--数组的下标*/
position dir_set[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

/*推断当前位置是否可行。即推断是路。还是墙*/
int pass(position p)
{
	if (m[p.x][p.y])
		return 0;
	else
		return 1;
}
/*将当前的步数填写在走的每一步正确的路上,当发现走不通时,会把当时写的信息

用‘1’抹掉,代表走不通。

*/
void footPrint(position p)
{
	m[p.x][p.y] = curstep;
}
/*计算下一步的坐标。di代表方向。本函数仅仅负责计算下一步坐标。不推断优先级*/
void nextPos(position *p, int di)
{
	(*p).x += dir_set[di].x;
	(*p).y += dir_set[di].y;
}
/*如上面的footPrint()凝视中提到的,当发现当前路走不通时,会用‘1’把走不通的

路堵上。

*/
void markPrint(position p)
{
	m[p.x][p.y] = 1;
}
/*迷宫程序的主函数。形參是一个指向不带头节点的栈的指针的指针,一个開始位置

,一个结束位置*/
int find_path(Stack_pNode * Maze_stack,position start,position end)
{
	position curpos = start;/*定义一个位置变量。用来保存当前的位置信息

*/
	SElem e;/*栈的元素。包含位置信息,和前进的方向*/
	do
	{
		if (pass(curpos)){ /*假设当前节点是路,则要将当前节点入栈。

并计算下一步前进方向*/
			footPrint(curpos);/*在前进节点上纪录当前的步数*/
			e.seat = curpos;/*保存位置信息*/
			e.di = 0;/*保存方向信息。默觉得向右*/
			push(Maze_stack, e);/*将位置信息入栈*/
			++curstep;/*步数加1*/
			if (curpos.x == end.x && curpos.y == end.y)/*假设当

前节点是出口。则返回运行成功的标识*/
				return 1;
			nextPos(&curpos, e.di);/*计算下一步的坐标。是依据当

前位置信息计算的,即已经入栈了的信息*/
		}
		else{/*假设当前节点是墙。则须要从栈取出之前走过的路,即沿原

路返回,在返回的过程中,还要不断的推断有没有其它的路*/
			if (!empty(*Maze_stack)){/*假设栈中有元素*/
				pop(Maze_stack,&e);
				--curstep;
				while (e.di == 3 && !empty(*Maze_stack)){/*

边向前回溯,边推断是否有其它的路可走*/
					markPrint(e.seat);/*用"墙"覆盖之前

填写的步数信息*/
					pop(Maze_stack,&e);
					--curstep;
				}
				if (e.di < 3){/*当找到了一个还有其它的路可

走之前走过的一个方块(最坏的情况是回到起始位置)*/
					++e.di;/*按优先级改变之前的行走方向

*/
					push(Maze_stack, e);/*再次入栈*/
					++curstep;/*再次将步数加1*/
					curpos = e.seat;/*再次纪录如今的位

置*/
					nextPos(&curpos, e.di);/*再次计算下

次的方向,有了以上的准备,即将进行下一次的循环*/
				}//end if
			}//end if
		}//end else
	} while (!empty(*Maze_stack));
	return 0;
}

/*打印迷宫*/
void printMaze()
{
	int i, j;
	for (i = 0; i < ROW+2; ++i)
	{
		for (j = 0; j < COL+2; ++j){
			printf("%2d ", m[i][j]);
		}
		printf("\n");
	}

}

int main()
{
	//stack_test();
	position start = { 1, 1 };/*迷宫入口*/
	position end = { 10, 10 };/*迷宫出口*/
	Stack_pNode maze_stack;/*声明一个栈,一会儿用来存放在迷宫中走过的位

置*/
	InitStack(&maze_stack);/*初始化栈*/
	if (find_path(&maze_stack, start, end)){
		reverse(&maze_stack);/*因为栈中存放的是倒置的信息,须要将栈

倒置*/
		print(maze_stack);/*打印带有走过的步数信息的迷宫地图*/
	}
	else{
		printf("Has no way to out of the maze.\n");
	}
	printMaze();

	return 0;
}
时间: 2024-10-29 10:47:41

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

C语言 解决迷宫问题练习

利用C语言来解决类似迷宫的问题,下面例子分别用两种方法来解决! [Problem] There is a maze as shown in the diagram below. In the maze in the form of a 100*100 matrix, the white background represents the road while the yellow background represents the wall. Assuming the upper left co

回溯法解决迷宫问题

现在有迷宫地图:(回溯法) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 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 1 1 1 1 1 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 1 1 1 1 1 1 1 将迷宫地图存于文件中,将文件里的信息依次读入到二维数组中,设置入口,先将

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

结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解答一万遍了,大多还是回溯法解决的. 关于回溯算法:个人理解为就是优化的穷举算法,穷举算法是指列出所有的可能情况,而回溯算法则是试探发现问题"剪枝"回退到上个节点,换一条路,能够大大提高求解效率. 具体到8皇后问题上来说,需要考虑以下几点: 1)将8个皇后定义为8行中的相对位置来标识,考虑增

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

可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是她能到达的,最近的出口离她有多远? 输入描述: 第一行为两个整数n和m,代表迷宫的行和列数 (1≤n,m≤30) 后面紧跟着n行长度为m的字符串来描述迷宫.'k'代表kotori开始的位置,'.'代表道路,'*'代表墙壁,'e'代表出口.保证输入合法. 输出描述: 若有出口可以抵达,则输出2个整数,

使用堆和队列数据结构解决迷宫问题

python实现迷宫问题的栈和队列的解决方法: #迷宫问题#表示迷宫的颜色,0表示路通,1表示围墙maze=[ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0

C语言解决八皇后问题

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /* this code is used to cope with the problem of the eight queens. 5 * array borad[9][9] is a virtual borad. 6 * line 0 and volumn 0 is ignored. 7 * at first we find a place to set a queen on it,

页面多语言解决办法

不罗嗦,直接上代码: <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>jQuery Lang JS Module Test Page</title> <script src="http://ajax.googleapis.

用BFS解决迷宫问题

在一个n*n的矩阵里走,从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走,求最短步数.n*n是01矩阵,0代表该格子没有障碍,为1表示有障碍物. int mazeArr[maxn][maxn]; //表示的是01矩阵 int stepArr[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; //表示上下左右4个方向 int visit[maxn][maxn]; //表示该点是否被访问过,防止回溯,回溯很耗时. 解题思路: BFS

以栈解决迷宫问题

怎么找到一个迷宫的出口呢.首先要知道迷宫长啥样,之后知道出入口,再之后就是找通路的过程了. 显然主要的部分是如何找通路.我们就举一个例子: 在这个迷宫中0就是墙,1就是路.那么我们可以用一个二维数组来表示这个迷宫.之后我们需要一种结构来实现我们表示位置的移动. struct Pos { size_t line; size_t row; }; 这个结构体通过记录行和列来表示现在处在迷宫的哪个位置. 现在就可以开始进行找通路的过程了.我们很容易想到通过试探当前位置的周围四个或三个位置来找到下一个应该