迷宫求解(自动生成)

子函数

stack.h

// - - - - - 栈的顺序存储表示 - - - - -
#define STACK_INIT_SIZE 100						   //存储空间初始分配量
#define STACKINCERMENT 10						   //存储空间分配增量
typedef bool Status;

typedef struct {
	SElemType* base;				//在栈构造之前和销毁之后,base的值为NULL
	SElemType* top;					//栈顶指针
	int stacksize;					//当前已分配的储存空间,以元素为单位
}SqStack;

// - - - - - 基本操作的函数原型说明 - - - - -
Status InitStack(SqStack& S);
//构造一个空栈S
Status DestroyStack(SqStack& S);
//销毁栈S,S不再存在
Status ClearStack(SqStack& S);
//把S置为空栈
Status StackEmpty(SqStack S);
//若栈S为空栈,则返回true,否则返回false
int StackLength(SqStack S);
//返回S的元素个数,即栈的长度
Status Push(SqStack& S, SElemType e);
//插入元素e为新的栈顶元素
Status Pop(SqStack& S, SElemType& e);
//若栈不空,删除S的栈顶元素,用e返回其值,并返回true;否则返回false

// - - - - - 基本操作的算法描述(部分) - - - - -
Status InitStack(SqStack& S) {
	S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!S.base)	exit(OVERFLOW);				//存储分配失败
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
	return true;
}// InitStack

Status DestroyStack(SqStack& S) {
	ClearStack(S);
	free(S.base);
	S.top = S.base = NULL;
	S.stacksize = 0;
	return true;
}// DestroyStack

Status ClearStack(SqStack& S) {
	if (S.top = S.base)
		return true;
	while (S.top != S.base) {
		S.top->ord = S.top->di = S.top->seat.x = S.top->seat.y = 0;
		S.top--;
	}
	S.top->ord = S.top->di = S.top->seat.x = S.top->seat.y = 0;
	S.base = S.top;
	return true;
}// ClearStack

Status StackEmpty(SqStack S) {
	if (S.top == S.base)
		return true;
	else
		return false;
}// StackEmpty

int StackLength(SqStack S) {
	SElemType* p = S.top; int i = 0;
	while (p != S.base) {
		p--;
		i++;
	}
	return i;
}

Status Push(SqStack& S, SElemType e) {
	if (S.top - S.base >= STACK_INIT_SIZE) {			//栈满,追加存储空间
		S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCERMENT) * sizeof(SElemType));
		if (!S.base)	exit(OVERFLOW);				//存储分配失败
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCERMENT;
	}
	
	*S.top = e;
	S.top++;
	return true;
}// Push

Status Pop(SqStack& S, SElemType& e) {
	if (S.top == S.base)
		return false;
	S.top--;
	e = *S.top;
	return true;
}// Pop

maze.h

#define M 25
#define N 25
typedef int** MazeType;//定义迷宫类型为二维数组指针
typedef struct {
	int x;			//横坐标
	int y;			//纵坐标
}PosType;			//坐标位置的元素类型
typedef struct {
	int ord;		//通道块在路径上的“序号”
	PosType seat;	//通道块在迷宫中的“坐标位置”
	int di;			//从此通道块走向下一通道块的方向
}SElemType;			//栈的元素类型
#include "stack.h"
// - - - - - 基本操作的函数原型说明 - - - - -
Status InitMaze(MazeType& maze);
	//初始化迷宫
Status DestroyMaze(MazeType& maze);
	//销毁迷宫
Status ClearMaze(MazeType& maze);
	//清空迷宫
Status CreateMaze(MazeType& maze, int m, int n);
	//随机生成长m+1宽n+1的迷宫,0墙1路,迷宫边界是墙
Status PrintMaze(MazeType maze, int m, int n);
	//打印迷宫, X代表墙,*代表路
Status Pass(MazeType maze, PosType p);
	//若当前位置p可以通过且未走过,maze[p.x][p.y]=1,则返回true;
	//否则返回false
void FootPrint(MazeType& maze, PosType p);
	//留下足迹,当前位置p已经走过,maze[p.x][p.y]=2
void MarkPrint(MazeType& maze, PosType p);
	//留下不能通过的标记,maze[p.x][p.y]=0
PosType NextPos(PosType p, int di);
	//返回当前位置p的下一位置,东di=1,南di=2,西di=3,北di=4
SElemType SetCurSElem(int ord, PosType seat, int di);
	//返回对应序号ord坐标seat及方向di的栈的元素
Status MazePath(SqStack& S, MazeType maze, PosType start, PosType end);
	//若迷宫maze存在从入口start到出口end的通道,则求得一条存放在栈中
	//(从栈底到栈顶),并返回true;否则返回false

// - - - - - 基本操作的算法描述 - - - - -
Status InitMaze(MazeType& maze) {
	int i;
	maze = (int**)malloc(M * sizeof(int*));
	if (!maze) exit(OVERFLOW);
	for (i=0; i < M; i++) {
		maze[i] = (int*)malloc(N * sizeof(int));
		if (!maze[i]) exit(OVERFLOW);
	}
	return true;
}

Status DestroyMaze(MazeType& maze) {
	ClearMaze(maze);
	free(maze);
	return true;
}

Status ClearMaze(MazeType& maze) {
	for (int i = 0; i < M; i++)
		free(maze[i]);
	return true;
}

Status CreateMaze(MazeType& maze, int m, int n) {
	int i, j;
	for (i = 0; i <= m; i++) {
		maze[i][0] = 0;
		maze[i][n] = 0;
		for (j = 1; j < n; j++) {
			if (!i || i == m) maze[i][j] = 0;
			else maze[i][j] = rand() % 2;
		}
	}
	return false;
}

Status PrintMaze(MazeType maze, int m, int n) {
	int i, j;
	cout << "迷宫高" << m + 1 << "宽" << n + 1 << endl;
	for (i = 0; i <= m; i++) {
		for (j = 0; j <= n; j++) {
			if (!maze[i][j]) cout << 'X';
			else if(maze[i][j]==1) cout << '*';
			else cout << '#';
		}
		cout << '\n';;
	}
	return true;
}

Status Pass(MazeType maze, PosType p) {
	if (maze[p.y][p.x] == 1)
		return true;
	return false;
}

void FootPrint(MazeType& maze, PosType p) {
	maze[p.y][p.x] = 2;
}

void MarkPrint(MazeType& maze, PosType p) {
	maze[p.y][p.x] = 0;
}

PosType NextPos(PosType p, int di) {
	switch (di){
	case 1:p.x++; break;
	case 2:p.y++; break;
	case 3:p.x--; break;
	case 4:p.y--; break;
	}
	return p;
}

SElemType SetCurSElem(int ord, PosType seat, int di) {
	SElemType s;
	s.ord = ord;
	s.seat.x = seat.x; s.seat.y = seat.y;
	s.di = di;
	return s;
}

Status MazePath(SqStack& S, MazeType maze, PosType start, PosType end) {
	InitStack(S); PosType curpos = start;	//设定当前位置为入口位置
	SElemType e;  int curstep = 1;			//探索第一步
	do {
		if (Pass(maze, curpos)) {
			FootPrint(maze, curpos);
			e = SetCurSElem(curstep, curpos, 1);
			Push(S, e);
			if (curpos.x == end.x && curpos.y == end.y)
				return true;
			curpos = NextPos(curpos, 1);
			curstep++;
		}//if
		else {
			if (!StackEmpty(S)) {
				Pop(S, e);
				while (e.di == 4 && !StackEmpty(S)) {
					MarkPrint(maze, e.seat); Pop(S, e);
				}//while
				if (e.di < 4) {
					e.di++; Push(S, e);
					curpos = NextPos(e.seat, e.di);
				}//if
			}//if
		}//else
	} while (!StackEmpty(S));
	return false;
}

主函数

Project3.2.4maze.cpp

#include <iostream>
using namespace std;
#include "maze.h"
#include <time.h>

int main(){
    srand((unsigned int)time(0));
    SqStack S;
    MazeType maze; PosType start, end;
    int i = 0, m, n;
    cout << "输入m n,迷宫高m+1宽n+1:\n";
    cin >> m >> n;
    InitMaze(maze); CreateMaze(maze, m, n);
    cout << "输出迷宫(X墙*路):\n";
    PrintMaze(maze, m, n);
    cout << "输入入口出口坐标(左上角为0 0右下角n" << n << 'm' << m << "):\n";
    cin >> start.x >> start.y >> end.x >> end.y;
    while (!MazePath(S, maze, start, end)) {
        cout << "迷宫不能通过\n重新生成迷宫(X墙*路):\n";
        CreateMaze(maze, m, n);
        PrintMaze(maze, m, n);
        cout << "重新输入坐标(左上角为0 0右下角n" << n << 'm' << m << "):\n";
        cin >> start.x >> start.y >> end.x >> end.y;
        DestroyStack(S);
        
    }
    SElemType* p = S.base;
    while (p != S.top) {
        cout << p->ord << ":(" << p->seat.x << ',' << p->seat.y << ')';
        switch (p->di) {
        case 1:cout << "东"; break;
        case 2:cout << "南"; break;
        case 3:cout << "西"; break;
        case 4:cout << "北"; break;
        }
        i++;
        if (i % 4 == 0)
            cout << '\n';
        p++;
    }
    cout << "\n输出走过的迷宫\nX 墙和死路; * 没有走的路; # 通路:\n";
    PrintMaze(maze, m, n);
    DestroyMaze(maze);
    return 0;
}

测试实例

测试
简单优化
优化

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求解迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方阵形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值