栈的应用之迷宫

一、普通迷宫
.h

# pragma once
# include"Stack.h"
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
#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;

// 初始化迷宫地图数据
void InitMap(Maze* m, int map[MAX_ROW][MAX_COL]);
// 检测迷宫的入口是否有效
int IsValidEnter(Maze* m, Position enter);
// 检测cur位置是否为迷宫的出口
int IsMazeExit(Maze* m, Position cur, Position enter);
// 检测当前位置是否为通路
int IsPass(Maze* m, Position cur);
// 走迷宫
void PassMazeNor(Maze* m, Position enter, Stack* s);
// 打印迷宫地图数据
void PrintMap(Maze* m);
// 打印路径
void PrintPath(Stack* s);
//>> 用递归的方式求解简单迷宫问题
void PassMaze(Maze* m, Position enter);
#define MAX_ROW 10
#define MAX_COL 10
typedef struct Maze
{
 int _map[MAX_ROW][MAX_COL];
}Maze;
// 初始化迷宫地图数据
void InitMap(Maze* m, int map[MAX_ROW][MAX_COL]);
// 检测迷宫的入口是否有效
int IsValidEnter(Maze* m, Position enter);
// 检测cur位置是否为迷宫的出口
int IsMazeExit(Maze* m, Position cur, Position enter);
// 检测当前位置是否是通路
int IsPass(Maze* m, Position cur);
// 走迷宫
void PassMaze(Maze* m, Position enter);
// 真正走迷宫的操作
int _PassMaze(Maze* m, Position entry, Position cur);
// 打印迷宫地图数据
void PrintMap(Maze* m);
// 打印走过的路径
void PrintPath(Stack* s);

.c
# include "migong.h"
void InitMap(Maze* m, int map[MAX_ROW][MAX_COL])
{
 int i = 0;
 int j = 0;
 if (NULL == m)
  return;
 for (i = 0; i < MAX_COL; ++i)
 {
  for (j = 0; j < MAX_ROW; ++j)
  {
   m->_map[i][j] = map[i][j];
  }
 }
}
int IsValidEnter(Maze* m, Position enter)
{
 if (NULL == m)
  return 0;
 if (0 == enter._x || MAX_COL - 1 == enter._x || 0 == enter._y || MAX_ROW - 1 == enter._y)
  return 1 == m->_map[enter._x][enter._y];
 return 0;
}
int IsMazeExit(Maze* m, Position cur, Position enter)
{
 //判断是否为入口
 if ((cur._x == enter._x) && (cur._y == enter._y))
  return 0;
 //不是入口,检查是否为出口
 if (0 == cur._x || MAX_COL-1 == cur._x || 0 == cur._y || MAX_ROW-1 == cur._y)
  return 1;
}
int IsPass(Maze* m, Position cur)
{
 return 1 == m->_map[cur._x][cur._y];
}
void PassMazeNor(Maze* m, Position enter, Stack* s)
{
 Position next;
 if (!IsValidEnter(m, enter))
 {
  printf("迷宫入口有误");
  return;
 }
 while (!StackEmpty(s))//只要出栈就有可能为空
 {
  Position cur = StackTop(&s);//取到入口元素
  m->_map[cur._x][cur._y] = 2;
  if (IsMazeExit(m, cur,enter))//如果为迷宫出口则退出
   return;
  //往上走
  next = cur;
  next._x -= 1;
  if (IsPass(m, next))
  {
   StackPush(s, next);
   continue;
  }
  //往左走
  next = cur;
  next._y -= 1;
  if (IsPass(m, next))
  {
   StackPush(s, next);
   continue;
  }
  //往右走
  next = cur;
  next._y += 1;
  if (IsPass(m, next))
  {
   StackPush(s, next);
   continue;
  }
  //往下走
  next = cur;
  next._x += 1;
  if (IsPass(m, next))
  {
   StackPush(s, next);
   continue;
  }
  //上下左右都走不通,标记为3
  m->_map[cur._x][cur._y] = 3;
  StackPop(s);
 }
}
void PrintMap(Maze* m)
{
 int i = 0;
 int j = 0;
 if (NULL == m)
  return;
 for (i = 0; i < MAX_COL; ++i)
 {
  for (j = 0; j < MAX_ROW; ++j)
  {
   printf("%d", m->_map[i][j]);
   printf("\n");
  }
 }
}
void PrintPath(Stack* s)
{
 Position top;
 while (StackSize(s)>1)
 {
  Position top = StackTop(s);
  printf("{%d,%d<---}", top._x, top._y);
  StackPop(s);
 }
 top = StackTop(s);
 printf("{%d,%d}", top._x, top._y);
}
void PassMaze(Maze* m, Position enter)
{
 Position next;
 if (!IsValidEnter(m, enter))
 {
  printf("迷宫入口有误");
  return;
 }
 _PassMaze(m, enter, enter);
}
int _PassMaze(Maze *m, Position entry, Position cur)
{
 if (IsPass(m, cur))
 {
  Position next;
  m->_map[cur._x][cur._y] = 2;
  if (IsMazeExit(m, entry, cur))
   return 1;
  //向上
  next = cur;
  next._x -= 1;
  if (_PassMaze(m, entry, next))
   return 1;
  //向左
  next = cur;
  next._y -= 1;
  if (_PassMaze(m, entry, next))
   return 1;
  //向右
  next = cur;
  next._y += 1;
  if (_PassMaze(m, entry, next))
   return 1;
  //向下
  next = cur;
  next._x += 1;
  if (_PassMaze(m, entry, next))
   return 1;
  m->_map[cur._x][cur._y] = 3;
 }
 return 0;
}

二、对复杂迷宫进行求解-- - 迷宫中可能有多条通路,多条路径有可能构成环

.h


#define MAX_ROW 4
#define MAX_COL 4
typedef struct Maze
{
 int _map[MAX_ROW][MAX_COL];
}Maze;
// 初始化迷宫地图数据
void InitMap(Maze* m, int map[MAX_ROW][MAX_COL]);
// 检测迷宫的入口是否有效
int IsValidEnter(Maze* m, Position enter);
// 检测cur位置是否为迷宫的出口
int IsMazeExit(Maze* m, Position cur, Position enter);
// 保存最短路径
void SaveShortPath(Stack* path, Stack* shortPath);
// 检测当前位置的下一步是否能够走通
int IsNextPass(Maze* m, Position cur, Position next);
// 走迷宫
void PassMaze(Maze* m, Position enter, Stack* ShortPath);
// 具体走迷宫方式
void __PassMaze(Maze* m, Position entry, Position cur, Stack* path, Stack* shortPath);
// 打印迷宫地图数据
void PrintMap(Maze* m);
// 打印路径
void PrintPath(Stack* s);

.c
void SaveShortPath(Stack* path, Stack* shortPath)
{
 int i = 0;
 int size = StackSize(path);
 for (; i < size; ++i)
  shortPath->_top = i;
}
int IsNextPass(Maze* m, Position cur, Position next)
{
 if (next._x <= 0 || next._x>MAX_ROW || next._y < 0 || next._y >= MAX_COL)
 {
  return 0;
 }
 if ((m->_map[next._x][next._y] == 1) || (m->_map[cur._x][cur._y] < m->_map[next._x][next._y]))
 {
  return 1;
 }
 return 0;
}
void PassMaze(Maze* m, Position enter, Stack* ShortPath)
{
 Stack Path, ShortPath;
 Position next;
 if (!IsValidEnter(m, enter))
 {
  printf("迷宫入口有误");
  return;
 }
 StackInit(&Path);
 __PassMaze(m, enter, enter, &Path, ShortPath);
}
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);
 if (IsMazeExit(m, cur, entry))
 {
  //更新最短路径
  if (StackEmpty(shortPath) || StackSize(path) < StackSize(shortPath))
   SaveShortPath(path, shortPath);//保存最短路径
  StackPop(path);
  return;
 }
 //上
 next = cur;
 next._x -= 1;
 if (IsNextPass(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 (IsNextPass(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 (IsNextPass(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 (IsNextPass(m, cur, next))
 {
  m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
  __PassMaze(m, entry, next, path, shortPath);
 }
 //当前位置走错了
 StackPop(path);
}

test.c
# include"migong.h"
# include"Stack.h"
void test1()
{
 Maze m;
 Stack s;
 Position enter;
 int map[MAX_COL][MAX_ROW] = { { 0, 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0 },
 { 0, 1, 0, 1, 0, 0 }, { 0, 1, 1, 1, 1, 1 }, { 0, 1, 0, 0, 0, 0 } };
 //InitMap(&m, (int *)map, MAX_COL*MAX_ROW);
 InitMap(&m, map);
 enter._x = 5;
 enter._y = 2;
 PrintPath(&m, map);
 StackInit(&s);
 PassMaze(&m, enter, &s);
 PrintMap(&s);
 Printf("{%d,%d}", top._x, top._y);
}
void test1()
{
 Maze m;
 Stack s;
 Position enter;
 int map[MAX_ROW][MAX_COL] = { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 } };
 InitMap(&m, map);
 enter._x = 3;
 enter._y = 1;
 PrintPath(&m, map);
 StackInit(&s);
 PassMaze(&m, enter, &s);
 PrintMap(&s);
 Printf("{%d,%d}", top._x, top._y);
}
int main()
{
 test();
 system("pause");
 return 0;
}
三、静态栈Stack.h中的修改为

# include"migong.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

# define MAX_SIZE 10
extern struct Position;
typedef Position DataType;
//typedef int DataType;
//typedef char DataType;
 
typedef struct Stack
{
 DataType _array[MAX_SIZE];
 int _top;
}Stack;
void StackInit(Stack *s);
void StackPush(Stack *s, DataType data);
int StackEmpty(Stack *s);
void StackPop(Stack *s);
DataType StackTop(Stack *s);
int StackSize(Stack *s);

猜你喜欢

转载自blog.csdn.net/xuruhua/article/details/80287327
今日推荐