0
点赞
收藏
分享

微信扫一扫

栈结构回顾(2)(寻路问题)

caoxingyu 2022-03-12 阅读 51

很久之前写的了,新人第六篇博客

默认从(1,1)开始走,默认方向是往右(0)走,准备往右走时先提前计算出往右走后落点处坐标,也就是(1,2),然后通过判断(1,2)是不是墙(判断是否为0),如果是墙就换个方向测试直到下一个落脚点不是墙,如果4个方向都是墙那就直接退出外循环,现在当测到往下的方向(1)时可以走那就退出内循环然后把当前位置(1,1)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,1),然后再把上一个落脚点堵住(置1),然后把方向改回默认方向(0),回到判断下一个是否为落脚点的语句里,像之前那样个个方向都判断,直到下一个落脚点不是墙为止,判断过后可以发现下一个落脚点就是(2,2),所以故技重施,把当前位置(2,1)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,2),再把上一个落脚点堵住(置1),然后方向也改回默认方向,重复上面步骤,然后判断过后可以发现下一个落脚点就是(2,3),所以故技重施,把当前位置(2,2)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,3),然后继续当到出口时把(2,3)入栈,然后此时坐标是(3,3)已经是地图的右下角故不满足循环条件退出循环把(3,3)入栈

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define R 3//出口
#define C 3
 
//数组里面去寻路:位置- ->行和列
struct position
{
	int row;//行
	int cols;//列
};
struct position pathStack[100];//存放路径-->栈内存
int stackTop = -1;//栈顶标记
int** maze = NULL;//二维数组去描述地图
int size = 0;//迷宫大小
int** makeArray(int row, int cols)
{
	int** array = (int**)malloc(sizeof(int) * row);
	for (int i = 0; i < cols; i++)
	{
		array[i] = (int*)malloc(sizeof(int) * cols);
	}
	return array;
}
//用户输入一个迷宫
void createMaze()
{
	printf("输入迷宫大小:\n");
	scanf("%d", &size);
	maze = makeArray(size + 2, size + 2);//加2 表示边框
	printf("输入迷宫:\n");
	for (int i = 1; i <= size; i++)
	{
		for (int j = 1; j <= size; j++)
		{
			scanf("%d", &maze[i][j]);
		}
	}
	//加边框:1 表示不可以走
	for (int i = 0; i <= size; i++)
	{
		maze[0][i] = maze[size + 1][i] = 1;//上下两行
		maze[i][0] = maze[i][size + 1];//左右两列
	}
}
//找路径
int findPath()
{
	//偏移属性描述出来
	struct position offset[4];//0-3表示四个方向
	//往右走
	offset[0].row = 0;
	offset[0].cols = 1;
	//往左走
	offset[2].row = 0;
	offset[2].cols = -1;
	//往下走
	offset[1].row = 1;
	offset[1].cols = 0;
	//往上走
	offset[3].row = -1;
	offset[3].cols = 0;
	//选定入口
	struct position here = { 1,1 };//当前位置
	//走迷宫:记录走过的路
	//走过ID路标记为1
	maze[1][1] = 1;
	int option = 0;//下一个移动方向
	int endOption = 3;//终止方向
	while (here.row != R || here.cols != C)
	{
		//相邻的位置做移动
		int rowNum, colsNum;//记录下标变化
		while (option <= endOption)
		{
			//行的变化=原位置+偏移量 ,偏移量由方向决定
			rowNum = here.row + offset[option].row;
			colsNum = here.cols + offset[option].cols;
			//一旦确定一个方向可以走,就需去下一步
			if (maze[rowNum][colsNum] == 0)
				break;//退出循环走另一边
			//不能走就换方向测试
			option++;
		}
		//可以走
		if (option <= endOption)
		{
			//走到下一个
			pathStack[++stackTop] = here;
			//改变当前位置
			here.row = rowNum;
			here.cols = colsNum;
			//走过的路标记--->堵上
			maze[rowNum][colsNum] = 1;
			option = 0;//置0 去找下一个位置
		}
		else//option==4;表示没有可走的地方
		{
			//回到上一步去
			if (stackTop == -1)
				return 0;//无路可走表示没有路径
			//出栈方式去回退到上一步
			struct position next = pathStack[stackTop];
			stackTop--;
			//方向的处理
			if (next.row == here.row)//行没变,左右走的
			{
				//逆过来偏移公式
				option = 2 + next.cols - here.cols;
			}
			else
			{
				option = 3 + next.row - here.row;
 
			}
			here = next;//当前位置变成回退后的位置
		}
	}
	if (here.row == R && here.cols == C)
	{
		pathStack[++stackTop] = here;
	}
	//打印到出口后的地图
	printf("\n");
	for (int i = 1; i <= size; i++)
	{
		for (int j = 1; j <= size; j++)
		{
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	return 1;
 
}
//打印路径
void printPath()
{
	printf("路径方式:\n");
	struct position curPos;
	while (stackTop != -1)
	{
		curPos = pathStack[stackTop];
		stackTop--;
		printf("(%d ,%d)--->", curPos.row, curPos.cols);
	}
	printf("\n");
}
 
int main()
{
	createMaze();
	if (findPath())
	{
		printPath();
	}
	else
	{
		printf("没有路径\n");
	}
	
 
	return 0;
}

举报

相关推荐

0 条评论