数据结构 栈 迷宫问题

1.题目

这里写图片描述
如上图,1为路,0为墙,求可以走出去的最短路径

2.基本思路

首先判断该点是否为入口,若是则把该位置的数值改为2,然后入栈,分别判断该点的上下左右是否可以走通,若可以则把可走通的位置改为前一个位置上的数值加一,若不能则判断下一个方向,都走不通则返回;当找到可走通的位置并修改完数值后,把该位置入栈,判断该位置是否为出口,若为出口,则把栈中元素的的个数与存放最短路径的栈中的元素的个数进行比较,若该栈中元素个数较少,则更新存放最短路径的栈;若不为出口则继续操作;然后递归调用这个函数(从判断上下左右是否可以走通开始),把可走通的位置传进函数中,当函数走回最外层递归时,则遍历完所有位置,程序结束,分别返回存放最短路径的栈中的元素
这里写图片描述

3.程序代码

前两个为栈的基本操作,后面是迷宫所需要的函数

//Stack.h

#ifndef __STACK_H__
#define __STACK_H__

#include <stdio.h>
#include <Windows.h>
#include <assert.h>

#define MAXSIZE 50

typedef struct Position
{
    int x;
    int y;
}DataType;

typedef struct StackNode
{
    DataType arr[MAXSIZE];
    int top;
}Stack, *pStack;

//初始化栈
void InitStack(pStack ps);
//入栈
void PushStack(pStack ps, DataType data);
//出栈
void PopStack(pStack ps);
//求栈顶元素
DataType TopStack(pStack ps);
//求栈中元素的个数
int SizeStack(pStack ps);
//求栈是否为空
int EmptyStack(pStack ps);


#endif // __STACK_H__
//Stack.c

#include "Stack.h"

void InitStack(pStack ps)
{
    assert(ps);

    ps->top = 0;
}

void PushStack(pStack ps, DataType data)
{
    assert(ps);

    ps->arr[ps->top++] = data;
}

int EmptyStack(pStack ps)
{
    assert(ps);

    return 0 == ps->top;
}

void PopStack(pStack ps)
{
    assert(ps);

    if (EmptyStack(ps))
    {
        return;
    }

    ps->top--;
}

int SizeStack(pStack ps)
{
    assert(ps);

    if (EmptyStack(ps))
    {
        return 0;
    }

    return ps->top;
}

DataType TopStack(pStack ps)
{
    assert(ps);
    if (EmptyStack(ps))
    {
        printf("栈为空!!!\n");
        return;
    }
    return ps->arr[ps->top - 1];
}

下面为迷宫所需的函数

//Maze.h
#ifndef __MAZE_H__
#define __MAZE_H__

#include "Stack.h"

#define ROW 6
#define COL 6

typedef struct Maze
{
    int _map[ROW][COL];

}Maze;

//初始化迷宫
void InitMaze(Maze *m, int map[ROW][COL]);
//打印迷宫
void PrintMaze(Maze m);
//判断该节点是否为入口
int IsEntry(DataType entry);
//判断该节点是否为出口
int IsExit(DataType top, DataType entry);
//移动
void Move(Maze *m, pStack Road, DataType entry);
//移动的路径
void MoveWay(Maze* m, DataType entry, DataType cur, pStack Road, pStack ShortRoad);
//判断是否可以移动
int CanMove(Maze* m, DataType cur, DataType next);

#endif // !__MAZE_H__
//Maze.c

#include "Maze.h"

void InitMaze(Maze *m, int map[ROW][COL])
{
    int x, y;

    for (x = 0; x < ROW; x++)
    {
        for (y = 0; y < COL; y++)
        {
            m->_map[x][y] = map[x][y];
        }
    }
}

void PrintMaze(Maze m)
{
    int x, y;

    for (x = 0; x < ROW; x++)
    {
        for (y = 0; y < COL; y++)
        {
            printf("%d  ", m._map[x][y]);
        }
        printf("\n");
    }
    printf("\n");
}

int IsEntry(DataType entry)
{
    if (0 == entry.x || 0 == entry.y || 5 == entry.x || 5 == entry.y)
    {
        return 1;
    }

    return 0;
}

int IsExit(DataType top, DataType entry)
{
    if ((top.x != entry.x || top.y != entry.y) && 
        (0 == top.x || 0 == top.y || 5 == top.x || 5 == top.y))
    {
        return 1;
    }

    return 0;
}

int CanMove(Maze* m, DataType cur, DataType next)
{
    assert(m);

    if (1 == m->_map[next.x][next.y] || 
        m->_map[next.x][next.y] > m->_map[cur.x][cur.y])
    {
        return 1;
    }

    return 0;
}

void MoveWay(Maze* m, DataType entry, DataType cur, pStack Road, pStack ShortRoad)
{
    DataType next;

    assert(m);

    PushStack(Road, cur);

    //判断是否为出口
    if (IsExit(cur, entry))
    {
        if (EmptyStack(ShortRoad) || (SizeStack(Road) < SizeStack(ShortRoad)))
        {
            int i = 0;
            int size = SizeStack(Road);

            for (; i < size; i++)
            {
                ShortRoad->arr[i] = Road->arr[i];
            }
        }

        PopStack(Road);
        return;
    }

    //向上移动
    next = cur;
    next.x = next.x - 1;
    if (CanMove(m, cur, next))
    {
        m->_map[next.x][next.y] = m->_map[cur.x][cur.y] + 1;
        MoveWay(m, entry, next, Road, ShortRoad);
    }

    //向左移动
    next = cur;
    next.y = next.y - 1;
    if (CanMove(m, cur, next))
    {
        m->_map[next.x][next.y] = m->_map[cur.x][cur.y] + 1;
        MoveWay(m, entry, next, Road, ShortRoad);
    }

    //向右移动
    next = cur;
    next.y = next.y + 1;
    if (CanMove(m, cur, next))
    {
        m->_map[next.x][next.y] = m->_map[cur.x][cur.y] + 1;
        MoveWay(m, entry, next, Road, ShortRoad);
    }

    //向下移动
    next = cur;
    next.x = next.x + 1;
    if (CanMove(m, cur, next))
    {
        m->_map[next.x][next.y] = m->_map[cur.x][cur.y] + 1;
        MoveWay(m, entry, next, Road, ShortRoad);
    }

    PopStack(Road);
}

void Move(Maze *m, pStack ShortRoad, DataType entry)
{
    Stack Road;
    InitStack(&Road);

    if (!IsEntry(entry))
    {
        printf("入口不合法!!!!\n");
    }

    m->_map[entry.x][entry.y] = 2;

    MoveWay(m, entry, entry, &Road, ShortRoad);
}
//test.c
#include "Maze.h"

void test()
{
    Stack ShortRoad;
    InitStack(&ShortRoad);
    Maze m;
    int map[ROW][COL] = { { 0, 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 } ,
                          { 0, 0, 1, 0, 0, 0 } };
    DataType entry = { 5, 2 };
    InitMaze(&m, map);
    printf("原始的迷宫\n");
    PrintMaze(m);
    Move(&m, &ShortRoad, entry);
    printf("走之后的迷宫\n");
    PrintMaze(m);
}

int main()
{
    test();
    system("pause");
    return 0;
}
4.执行结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值