数据结构:带环迷宫如何求最短路径(栈)


遇到下一位为1,或者下一位置大于当前位置,则为通路

向后走是,将前一个节点值+1,标记节点

按照上-左-右-下的顺序

简单迷宫实现:栈结构实现:迷宫出口判断 - CSDN博客 https://blog.csdn.net/W_J_F_/article/details/80165506 

递归实现迷宫:数据结构:递归实现简单迷宫 - CSDN博客 https://blog.csdn.net/W_J_F_/article/details/80233310 

栈实现:数据结构:静态栈与动态栈的实现 - CSDN博客 https://blog.csdn.net/W_J_F_/article/details/80082296 




maze.h

#pragma once  
#define MAX_ROW 6  
#define MAX_COL 6  

typedef struct Position
{
	int _x;
	int _y;
}Position;

typedef struct Maze
{
	int _map[MAX_ROW][MAX_COL];

}Maze, *PMaze;

// 栈的初始化   
void InitMaze(Maze *m, int map[][MAX_COL]);

// 检测入口是否为有效入口   
int IsValidEntry(Maze *m, Position entry);

// 检测cur位置是否是通路   
int IsPass(Maze *m, Position cur, Position next);

// 检测Cur是否在出口   
int IsExit(Maze *m, Position cur, Position entry);

// 走迷宫   
void PassMaze(Maze *m, Position entry, Stack* shortPath);

// 打印迷宫   
void PrintMaze(Maze *m);

void SaveShortPath(Stack* path, Stack* shortPath);

void _PassMaze(Maze* m, Position entry, Position cur, Stack* path, Stack* shortPath);

maze.c

#include "stack.h"  
#include "Maze.h"  

//1. 用栈对简单迷宫进行求解,迷宫只有一个出口  
//采用循环方式实现  

void PrintMaze(Maze *m)//打印迷宫  
{
	int i = 0;
	assert(m);

	for (; i < MAX_ROW; ++i)
	{
		int j = 0;
		for (; j < MAX_COL; ++j)
		{
			printf("%d ", m->_map[i][j]);
		}
		printf("\n");
	}

}

void InitMaze(Maze *m, int map[][MAX_COL])//迷宫初始化,就是将地图中的值赋给迷宫  
{
	int i = 0;
	assert(m);

	for (; i < MAX_ROW; ++i)
	{
		int j = 0;
		for (; j < MAX_COL; ++j)
		{
			m->_map[i][j] = map[i][j];
		}
	}
}

int IsValidEntry(Maze *m, Position entry)//检测迷宫入口是否合法  
{
	assert(m);

	//必须位于迷宫边界且值为1  
	if ((entry._x == 0 || entry._y == 0 || entry._x == MAX_ROW - 1
		|| entry._y == MAX_COL - 1) && (m->_map[entry._x][entry._y] == 1))
		return 1;
	return 0;
}

int IsPass(Maze *m, Position cur, Position next)// 检测cur位置是否是通路   
{
	assert(m);

	//值为1且不能越界  
	if ((next._x >= 0 && next._x <= MAX_ROW - 1) &&
		(next._y >= 0 && next._y <= MAX_COL - 1) &&
		m->_map[next._x][next._y] == 1 ||                   //如果迷宫没走过 值为1则为通路
		m->_map[next._x][next._y] > m->_map[cur._x][cur._y])//如果迷宫走过,next>cur则为通路
		return 1;

	return 0;

}

int IsExit(Maze *m, Position cur, Position entry)// 检测Cur是否在出口   
{
	assert(m);

	//出口位置就是处于边界值为1且不能是入口  
	if ((cur._x == 0 || cur._y == 0 || cur._x == MAX_ROW - 1
		|| cur._y == MAX_COL - 1) && (m->_map[cur._x][cur._y] == 1)
		&& ((cur._x != entry._x) || (cur._y != entry._y)))
		return 1;

	return 0;
}

void PassMaze(Maze *m, Position entry, Stack* shortPath)
{
	Stack path;
	//检测入口是否合法
	if (!IsValidEntry(m, entry))
	{
		printf("迷宫非法!\n");
		return;
	}
	StackInit(&path,100);
	_PassMaze(m, entry, entry, &path, shortPath);
	int i = 0;
	int size = StackSize(shortPath);
	for (;i < size;++i)
	{
		printf("[%d][%d]->", shortPath->arr[i]._x, shortPath->arr[i]._y);
	}

}

void _PassMaze(Maze* m, Position entry, Position cur, Stack* path, Stack* shortPath)
{
	Position next;
	if (StackEmpty(path))
		m->_map[cur._x][cur._y] = 2;
	
	StackPush(path,cur);
	
		printf("[%d][%d]->", cur._x, cur._y);

	if (IsExit(m, cur, entry))//判断是否是出口
	{
		if(StackEmpty(shortPath) || StackSize(path) > StackSize(shortPath))
			SaveShortPath(path,shortPath);
		StackPop(path);
		return;
	}
	//上
	next = cur;
	next._x -= 1;
	if (IsPass(m, cur, next))
	{
		m->_map[next._x][next._y]= m->_map[cur._x][cur._y] + 1;
		_PassMaze(m,entry,next,path,shortPath);
	}
	//左
	next = cur;
	next._y -= 1;
	if (IsPass(m, cur, next))
	{
		m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
		_PassMaze(m, entry, next, path, shortPath);
	}
	//右
	next = cur;
	next._y += 1;
	if (IsPass(m, cur, next))
	{
		m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
		_PassMaze(m, entry, next, path, shortPath);
	}
	//下
	next = cur;
	next._x += 1;
	if (IsPass(m, cur, next))
	{
		m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
		_PassMaze(m, entry, next, path, shortPath);
	}
	
}

void SaveShortPath(Stack* path, Stack* shortPath)
{
	int i = 0,size;
	assert(path);
	assert(shortPath);
	size = StackSize(path);
	for (;i < size;++i)
	{
		shortPath->arr[i] = path->arr[i];
	}
	shortPath->size = i;
	
}

test()

#include "stack.h"  
#include "maze.h"  

void TestMaze()
{
	Position entry;
	Maze m;
	Stack s;
	Stack path;
	int map[6][6] = {
	{ 0,0,0,0,0,0 },
	{ 0,1,0,0,0,0 },
	{ 0,1,1,1,1,0 },
	{ 0,1,0,0,1,1 },
	{ 0,1,1,1,1,0 },
	{ 0,1,0,0,0,0 }, 
	};
	StackInit(&s, 10);
	StackInit(&path, 10);

	InitMaze(&m, map);

	PrintMaze(&m);
	entry._x = 5;
	entry._y = 1;

	printf("\n");
	PassMaze(&m, entry, &s);
	printf("\n");

	printf("\n");
	PrintMaze(&m);

}
int main()
{
	TestMaze();//测试迷宫  
	system("pause");
	return 0;
}

stack.c

#include "stack.h"  
#include "maze.h"  

void StackInit(Stack *S, int capacity)//栈初始化  
{
	S->arr = (DataType*)malloc(capacity * sizeof(DataType));
	if (NULL == S->arr)
	{
		printf("申请空间失败!\n");
		return;
	}
	S->capacity = capacity;
	S->size = 0;
}


void AddCapacity(Stack *S)//扩容  
{
	if (NULL == S->arr)
	{
		printf("扩容失败\n");
		return;
	}
	S->capacity = (DataType*)realloc(S->arr, sizeof(DataType) * (S->capacity) * 2);//扩容为原来的二倍  
	if (NULL == S->arr)
	{
		printf("空间扩增失败!!!\n");
		return;
	}
	S->capacity = 2 * (S->capacity);
}

void PrintfStack(Stack *S)//打印栈  
{
	int i = 0;
	if (NULL == S->arr)
	{
		printf("打印失败\n");
		return;
	}
	for (;i<S->size;i++)
	{
		printf("%d \n", &S->arr[i]);
	}
	printf("\n");
}

void StackPush(Stack *S, DataType data)//入栈  
{
	if (NULL == S->arr)
	{
		printf("入栈失败\n");
		return;
	}
	if (S->capacity == S->size)//空间已满  
	{
		AddCapacity(S);
	}
	S->arr[S->size] = data;
	S->size++;
}

void StackPop(Stack *S)//出栈  
{
	if (NULL == S->arr)
	{
		printf("出栈失败\n");
		return;
	}
	S->size--;
}

DataType StackTop(Stack *s)//获取栈顶元素  
{
	return s->arr[s->size - 1];
	/* int ret = 0;
	if(NULL == S->arr)
	{
	printf("获取栈失败\n");
	return;
	}
	if(0 == S->size)
	{
	printf("栈为空!\n");
	return;
	}

	printf("栈顶元素为:%d \n", S->arr[S->size - 1]);*/
}

int StackSize(Stack *S)//获取元素个数  
{
	if (NULL == S->arr)
	{
		printf("获取栈失败\n");
		return 0;
	}
	return S->size;
	//printf("元素个数为:%d\n", S->size);
}

int StackEmpty(Stack *S)//检测栈是否为空  
{
	if (NULL == S->arr)
	{
		printf("获取栈失败\n");
		return 0;
	}
	if (S->size == 0)
	{
		return 1;
	}
	return 0;
}

stack.h

#pragma once  
#include <assert.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  

typedef struct Position DataType;

typedef struct Stack
{
	DataType *arr;//指向动态空间的指针  
	int capacity;//空间总容量  
	int size;//有效元素个数  
}Stack, *PStack;

// 栈的初始化   
void StackInit(Stack *S, int capacity);

// 入栈   
void StackPush(Stack *S, DataType data);

// 出栈   
void StackPop(Stack *S);

// 获取栈顶元素   
DataType StackTop(Stack *S);

// 获取栈中元素个数   
int StackSize(Stack *S);

// 检测栈是否为空   
int StackEmpty(Stack *S);

猜你喜欢

转载自blog.csdn.net/w_j_f_/article/details/80556343
今日推荐