栈实现迷宫探索问题

该死的数据结构实验啊,难写的要死。。。。555555翻了很多博客,抄一个还是错的,现在某些人的博客真是没良心,坑孩子啊55555,自己百般测试,终于是写出来一个,亲测有用

基本思路就是从入口开始,判断当前坐标是否可走,可走的话就入栈,然后按照上下左右四个方向依次尝试,下一个节点能走就继续尝试,不能走就返回栈顶元素继续尝试下一个方向,然后入栈刚刚出栈的这个坐标,当四个方向走完的时候,再次返回这个弹出来的坐标就不能入栈了,继续弹出一个坐标,尝试弹出来的这个坐标的下一个方向。。。。依次循环,直到栈为空,或者走到终点。栈为空说明没有出路。

还有个小心得哈,就是写题之前好好想想要不要用指针,反正混着用很麻烦,这次就是把Position改成指针又改回来,反反复复,麻烦死了。

还有就是指针一定要malloc,要不然出错的,这次就是老是吧该分配内存的没分配,直接拿着个没初始化的指针瞎比划,浪费了很多时间,只有是变量的结构体才能直接创建而不用初始化。

#include <iostream>
#include <cstdio>
using namespace std;

#define STACKSIZE 100  //栈大小
#define ENTER_ROW 0   //入口行列
#define ENTER_COL 1
#define OUT_ROW 8    //出口行列
#define OUT_COL 9
#define N 10    //迷宫大小

typedef struct p   //坐标
{
    int x, y;
}Position;

typedef struct d
{
    Position position;
    int dictionary;    //记录走过了多少方向
}DicPosition;

typedef struct s    //定义栈
{
    DicPosition array[STACKSIZE];
    int rear;
}*Stack;

//定义迷宫
int mazing[N][N] = {
        {2,0,2,2,2,2,2,2,2,2},//0
        {2,0,0,2,0,0,0,2,0,2},//1
        {2,0,0,2,0,0,0,2,2,2},//2
        {2,0,0,0,0,2,2,0,0,2},//3
        {2,0,2,2,2,0,2,0,2,2},//4
        {2,0,0,0,2,0,0,0,0,2},//5
        {2,0,2,0,0,0,2,0,0,2},//6
        {2,0,2,2,2,0,2,2,0,2},//7
        {2,2,0,0,0,0,0,0,0,0},//8
        {2,2,2,2,2,2,2,2,2,2} //9
};

Stack initStack();      //初始化栈
bool isEmpty(Stack stack);      //空
bool isFull(Stack stack);       //满
bool push(Stack stack, DicPosition dicPosition); //入栈
int pop(Stack stack, DicPosition &dicPosition);    //出栈
bool check(Position position);   //检查这个坐标是否可走
Position nextPosition(Position position, int direction); //获得下一个可走坐标


int main() {
    Stack stack = initStack();
    Position position;
    position.x = ENTER_ROW;
    position.y = ENTER_COL;
    DicPosition dicPosition;
    dicPosition.position.x = position.x;
    dicPosition.position.y = position.y;
    dicPosition.dictionary = 0;
    push(stack, dicPosition);    //入口一定能走
    bool flag = false;
    while (!isEmpty(stack))
    {
        if (check(position))     //说明能走,就赋值为10,入栈,继续下一步
        {
            if (flag)        //为维持不空,只对首元素入栈时起作用
            {
                dicPosition.position = position;
                dicPosition.dictionary = 0;
                push(stack, dicPosition);
            }
            mazing[position.x][position.y] = 10;
            flag = true;

            //到达出口
            if (position.x == OUT_ROW && position.y == OUT_COL)
                break;

            position = nextPosition(position, 1);        //继续探索下一个坐标
            stack->array[stack->rear-1].dictionary = 1;     //栈顶元素走过一个方向,计数为1
        } else  //不能走,就取出当前栈顶元素,尝试下一个方向
        {
            if (!isEmpty(stack))    //栈不空
            {
                pop(stack, dicPosition);
                while (dicPosition.dictionary == 4 && !isEmpty(stack))   //检查是否四个方向都走过
                {
                    mazing[dicPosition.position.x][dicPosition.position.y] = 9;  //标记9是已经走过
                    pop(stack, dicPosition);
                }

                if (dicPosition.dictionary < 4)   //四个方向没走完,继续下一个方向
                {
                    position = nextPosition(dicPosition.position, dicPosition.dictionary+1);
                    dicPosition.dictionary++;
                    push(stack, dicPosition);     //上面弹出的栈顶元素没有走完四个方向,重新入栈
                }
            }
        }
    }

    for (int i=0; i<N; i++)
    {
        for (int j=0; j<N; j++)
        {
            printf("%3d ", mazing[i][j]);
        }
        printf("\n");
    }

    free(stack);

    return 0;
}

Stack initStack()
{
    Stack stack = (Stack) malloc(sizeof(s));
    stack->rear = 0;
    return stack;
}

bool isEmpty(Stack stack)
{
    return stack->rear == 0;
}

bool isFull(Stack stack)
{
    return stack->rear == STACKSIZE - 1;
}

bool push(Stack stack, DicPosition dicPosition)
{
    if (isFull(stack))
    {
        printf("栈满!");
        return false;
    } else
    {
        stack->array[stack->rear] = dicPosition;
        stack->rear++;
    }
}

int pop(Stack stack, DicPosition &dicPosition)
{
    if (isEmpty(stack))
    {
        printf("栈空");
        return 0;
    } else
    {
        stack->rear--;
        dicPosition = stack->array[stack->rear];
    }
}

bool check(Position position)
{
    if (mazing[position.x][position.y] != 0)    //走不通
        return false;
    if (position.x < 0 || position.x >= N)   //行越界
        return false;
    if (position.y < 0 || position.y >= N)   //列越界
        return false;
    return true;
}

Position nextPosition(Position position, int direction)
{
    Position temp = position;
    temp.x = position.x;
    temp.y = position.y;
    switch (direction)
    {
        case 1:{
            temp.x -= 1; //上
            break;
        }
        case 2:{
            temp.x += 1;   //下
            break;
        }
        case 3:{
            temp.y -= 1;   //左
            break;
        }
        case 4:{
            temp.y += 1;  //右
            break;
        }
    }
    return temp;
}

 

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/yan454790122/article/details/83756360
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞