堆栈的应用 - 老鼠走迷宫问题

#include <stdio.h>
#include <stdlib.h>

/*
    所用的堆栈是链表形式, 并且带有头结点, 整个迷宫地图有4种状态,
    0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
*/

// 老鼠的移动始终遵循 上右下左 规律
// MAZE是迷宫数组
#define UP MAZE[x-1][y]     // 上
#define RIGHT MAZE[x][y+1]  // 右
#define DOWN MAZE[x+1][y]   // 下
#define LEFT MAZE[x][y-1]   // 左
#define EX 2    // 出口x坐标
#define EY 3    // 出口y坐标
#define MAZEX 10 // 迷宫竖向长度
#define MAZEY 12 // 迷宫横向长度

struct list {
    int x;
    int y;
    struct list* next;
};

typedef struct list node;
typedef struct list* link;

// 定义迷宫数组 0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
/* 测试地图1 4x4
int MAZE[MAZEX][MAZEY] = {
    2, 2, 2, 2,
    2, 0, 0, 2,
    2, 0, 0, 0,
    2, 2, 2, 2
};
*/
// 测试地图 2 5x5
/*
int MAZE[MAZEX][MAZEY] = {
    2, 2, 2, 2, 2,
    2, 0, 0, 2, 2,
    2, 0, 2, 0, 2,
    2, 0, 0, 0, 2,
    2, 2, 2, 0, 2
};
*/
// 测试地图 3 10x12
int MAZE[MAZEX][MAZEY] = {
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2,
    2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
};

// 函数声明
void push (link head, int x, int y);
int pop (link head, int* x, int* y);
int isExit (int x, int y);
void printMaze ();
void printStack (link stack);

int main () {
    int i;
    int j;
    int x = 1; // 老鼠当前位置, 初始状态表示入口x坐标
    int y = 1; // 老鼠当前位置, 初始状态表示入口y坐标

    // 栈的初始化
    link pathHead = (node*)malloc(sizeof(node));
    pathHead->next = NULL;

    // 打印迷宫路径图
    printf("0通路 1走过的路 2墙壁 3已经走过并确认为错误路径\n");
    printf("初始迷宫地图: \n");
    printMaze();

    // 0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
    MAZE[x][y] = 1; // 初始点标记为1
    push(pathHead, x, y); // 首先把初始点压入栈中存放
    while (isExit(x, y) == 0) {
        printf("老鼠现在的位置: %d, %d\n", x, y);
        if (UP == 0) {
            x--;
            MAZE[x][y] = 1; // 走过的路径标记为1
            push(pathHead, x, y);
        } else if (RIGHT == 0) {
            y++;
            MAZE[x][y] = 1; // 走过的路径标记为1
            push(pathHead, x, y);
        } else if (DOWN == 0) {
            x++;
            MAZE[x][y] = 1; // 走过的路径标记为1
            push(pathHead, x, y);
        } else if (LEFT == 0) {
            y--;
            MAZE[x][y] = 1; // 走过的路径标记为1
            push(pathHead, x, y);
        } else {
            printf("当前位置上下左右都不通, 回退!\n");
            pop(pathHead, &x, &y); // 把当前的坐标也就错误坐标, 弹出去
            MAZE[x][y] = 3; // 标记当前死路为3

            // 让x和y回到上一次的位置
            x = pathHead->next->x;
            y = pathHead->next->y;
        }
    }

    printf("老鼠走过的路径如下\n");
    printMaze();
    return 0;
}

// 入栈
void push (link head, int x, int y) {
    link newNode = (node*)malloc(sizeof(node));
    newNode->x = x;
    newNode->y = y;

    newNode->next = head->next;
    head->next = newNode;
}

// 出栈
// 运行结果: 直接对当前x和y的位置进行修改
int pop (link head, int* x, int* y) {
    if (head->next == NULL) {
        printf("栈空\n");
        return 0;
    }

    link popNode = head->next;
    head->next = popNode->next;
    *x = popNode->x;
    *y = popNode->y;
    free(popNode);
    return 1;
}

// 检查是否已经走到出口
// 参数: x 当前x坐标, y当前y坐标
// 返回值: 到出口返回1 ,不在出口返回0
int isExit (int x, int y) {
    // 检查当前位置的上右下左4个位置, 是否已经超出迷宫范围
    // 即可判断, 当前位置是否是出口
    // 也就是说如果当前位置是出口, 当前的位置一定是在迷宫边界上
    if (x <= 0 || x > MAZEX - 1 || y <= 0 || y >= MAZEY - 1) {
        printf("成功找到出口\n");
        printf("\n");
        return 1;
    } else {
        printf("还没找到出口\n");
        printf("\n");
        return 0;
    }
}

// 打印迷宫数组
void printMaze () {
    int i;
    int j;
    for (i=0; i<MAZEX; i++) {
        for (j=0; j<MAZEY; j++) {
			printf("%2d", MAZE[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    printf("\n");
}

// 打印堆栈
void printStack (link stack) {
    int length = 0;
    stack = stack->next;
    while (stack) {
        printf("%d\t%d\n", stack->x, stack->y);
        length += 1;
        stack = stack->next;
    }
    printf("当前一共存储了%d个路径\n", length);
    printf("\n");
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凯尔kyle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值