Use stacks to navigate the maze

Preliminary knowledge

Forward declaration header file: https://blog.csdn.net/hanzheng6602/article/details/80031130

Dynamic sequence table: https://blog.csdn.net/hanzheng6602/article/details/79917391

Expansion: Find the shortest path in a maze with a ring

https://blog.csdn.net/hanzheng6602/article/details/80054038

Stack Application - Bracket Matching and Reverse Polish Expressions

https://blog.csdn.net/hanzheng6602/article/details/80077502

result:
write picture description here


The idea of ​​​​using the stack to walk the maze : starting from the entry point, first mark the entry node as 2, indicating that it has been passed. Then test in four directions. If it is a legal point, mark it, put it on the stack, and check whether it is an exit. If it is not, take the vertex of the stack and start to test all around. If all four sides are illegal, pop the point from the stack.

Judgment point function: it is within the map boundary, not the entry node, and has not passed through

Determine the exit function: it is a point on the boundary, and it is a point that can be walked

Recursive idea : first mark the incoming point 2, push it into the stack, and form a sub-problem - how to walk the rest of the maze? From the entry point to the surrounding test, if any direction is successful, return 1, that is, the whole maze has a solution, if this direction fails, it means that this direction will fail no matter how you go in the future, and you have to pop this knot. point. When all four directions fail, pop the entry point from the stack and return 0.


stack.h

The dynamic stack is changed according to the dynamic sequence, which involves dynamic memory development of its pointer. The array is used as an array, and the array stores the encapsulated Position coordinates.

#pragma once
extern struct position;
typedef struct position Position;
#define Datatype Position
//动态栈
typedef struct stack {
    Datatype *array;
    int top;
    int capacity;
}Stack;

void init(Stack *s);//初始化
void pushBack(Stack *s, Datatype data);//入栈
void pop(Stack *s);//出栈
Datatype top(Stack *s);//获取栈顶元素
int  checkCapacity(Stack *s);//检查容量,扩容
void destory(Stack* s);//销毁栈   
int isEmpty(Stack* s);//判空
int stackSize(Stack * s);//获取栈元素个数
void printStack(Stack * min);//从底到顶打印栈

maze.h

#pragma once
#define ROW 6
#define COL 6
extern struct stack;
typedef struct stack Stack;
//对坐标进行封装
typedef struct position {
    int x;
    int y;
}Position;

int map[ROW][COL];//迷宫
void initMap(int maze[ROW][COL]); //初始化map
int isValidEntry(int maze[ROW][COL], Position entry);//检测合法入口
//检查是否可以走
int isValidPath(int maze[ROW][COL], Position next);
//检查是不是出口
int isExit(int maze[ROW][COL], Position next, Position entry);
//栈实现走迷宫
int passMaze(int maze[ROW][COL], Position entry, Stack* path);
//递归走迷宫
int passMazeR(int maze[ROW][COL], Position cur, Position entry, Stack* path);
void printMap(); //打印迷宫

stack.c

#include "stack.h"
#include "maze.h"
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
void init(Stack *s)
{
    assert(s);
    s->capacity = 10;
    s->array = (Datatype*)malloc(sizeof(Datatype)*(s->capacity));
    if (NULL == s->array) {
        printf("分配失败");
    }
    s->top = 0;
}

void pushBack(Stack *s, Datatype data)
{
    assert(s);
    if (checkCapacity(s)) {
        s->array[s->top] = data;
        s->top++;
    }
}
int checkCapacity(Stack *s)
{
    assert(s);
    //需要扩容了
    if (s->top == s->capacity) {
        Datatype * new = NULL;
        new = (Datatype*)realloc(s->array, sizeof(Datatype) * 2 * (s->capacity)); //扩容两倍
        if (NULL == new) {
            return 0;
        }
        s->array = new;
        s->capacity *= 2;
    }
    return 1;
}

void pop(Stack *s)
{
    assert(s);
    if (0 == s->top) {
        return;
    }
    s->top--;
}

Datatype top(Stack *s)
{
    if (0 == s->top) {
        printf("没有元素可取了");
        return s->array[0];
    }
    return s->array[(s->top) - 1];
}

void destory(Stack* s)
{
    free(s->array);
    s->array = NULL;
    s->capacity = 0;
    s->top = 0;
}
//判空
int isEmpty(Stack* s)
{
    return s->top ? 0 : 1;
}
//获取栈元素个数
int stackSize(Stack * s)
{
    return s->top;
}
//从底到顶打印栈
void printStack(Stack * min)
{
    int i = 0;
    for (i = 0; i < min->top; i++) {
        printf("(%d, %d ) ", min->array[i]);
    }
    printf("\n");
}

maze.c

#include "maze.h"
#include "stack.h"
#include <malloc.h>
void initMap(int maze[ROW][COL])
{
    int i, j;
    for (i = 0; i < ROW; i++) {
        for (j = 0; j < COL; j++) {
            map[i][j] = maze[i][j];
        }
    }
}
/*******************************栈实现走迷宫*******************************/
int passMaze(int maze[ROW][COL], Position entry, Stack* path)
{   
    //检测合法入口
    if (!isValidEntry(maze, entry)) {
        return 0;
    }
    maze[entry.x][entry.y] = 2;     //标记已走的为2
    pushBack(path, entry);          //走一步入口节点
    Position cur;                   //记录当前走的位置
    //上右下左走
    while (!isEmpty(path)) {
        cur = top(path);
        if (isExit(maze, cur, entry)) {
            maze[cur.x][cur.y] = 2;
            return 1;
        }
        Position next;
        next = cur;
        next.x -= 1;
        if (isValidPath(maze, next)) {
            maze[next.x][next.y] = 2;
            pushBack(path, next);
            continue;
        }

        next = cur;
        next.y += 1;
        if (isValidPath(maze, next)) {
            maze[next.x][next.y] = 2;
            pushBack(path, next);
            continue;
        }

        next = cur;
        next.x += 1;
        if (isValidPath(maze, next)) {
            maze[next.x][next.y] = 2;
            pushBack(path, next);
            continue;
        }

        next = cur;
        next.y -= 1;
        if (isValidPath(maze, next)) {
            maze[next.x][next.y] = 2;
            pushBack(path, next);
            continue;
        }

        //四个方向均无法走,回退一步
        maze[cur.x][cur.y] = 3;  //标记为3可以看出哪些点是回退的
        pop(path);

    }
    return 0;
}

/*******************************递归实现走迷宫*******************************/
int passMazeR(int maze[ROW][COL], Position cur, Position entry, Stack* path)
{
    if (!isValidEntry(maze, entry)) {
        return 0;
    }
    //先标记入口点
    maze[entry.x][entry.y] = 2;
    //求解子迷宫问题
    return _passMazeR(maze, entry, entry, path);
}

int _passMazeR(int maze[ROW][COL], Position cur, Position entry, Stack* path)
{
    //入栈当前点
    pushBack(path, cur);
    if (isExit(maze, cur, entry)) {
        return 1;
    }
    //上右下左走
    Position tmp = cur; //下一个要试探的位置
    tmp.x -= 1;
    if (isValidPath(maze, tmp)) {
        maze[tmp.x][tmp.y] = 2;
        if (_passMazeR(maze, tmp, entry, path))
            return 1;
    }

    tmp = cur;
    tmp.y += 1;
    if (isValidPath(maze, tmp)) {
        maze[tmp.x][tmp.y] = 2;
        if (_passMazeR(maze, tmp, entry, path))
            return 1;
    }

    tmp = cur;
    tmp.x += 1;
    if (isValidPath(maze, tmp)) {
        maze[tmp.x][tmp.y] = 2;
        if (_passMazeR(maze, tmp, entry, path))
            return 1;
    }

    tmp = cur;
    tmp.y -= 1;
    if (isValidPath(maze, tmp)) {
        maze[tmp.x][tmp.y] = 2;
        if (_passMazeR(maze, tmp, entry, path))
            return 1;
    }
    //四个方向均尝试,出栈
    pop(path);
    return 0;
}

/*******************************辅助函数*******************************/
int isValidEntry(int maze[ROW][COL], Position entry)//检测合法入口
{
    if (entry.x < 0 || entry.y < 0 || entry.x >= ROW || entry.y >= COL) {
        return 0;
    }
    return maze[entry.x][entry.y];
}
int isValidPath(int maze[ROW][COL], Position next)//检查是否可以走
{
    if (next.x < 0 || next.y < 0 || next.x >= ROW || next.y >= COL) {
        return 0;
    }
    else if (1 == maze[next.x][next.y]) {
        return 1;
    }
    return 0;
}
int isExit(int maze[ROW][COL], Position next, Position entry)//检查是不是出口
{
    //不能是入口
    if (next.x == entry.x && (next.y == entry.y)) {
        return 0;
    }
    //因为进来的都是有效点,所以只用判断是不是边界
    else if ((0 == next.x || 0 == next.y || (ROW - 1) == next.x || (COL - 1) == next.y)) {

        return 1;
    }
    return 0;
}
void printMap()
{
    int i, j;
    for (i = 0; i < ROW; i++) {
        for (j = 0; j < COL; j++) {
            printf("%d ", map[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

test.c

#include "stack.h"
#include "maze.h"
#include <Windows.h>
int main()
{
    Stack path;
    init(&path);
    int tmp[ROW][COL] = {
        { 0,0,0,0,0,0 },
        { 0,1,0,1,1,0 },
        { 0,1,1,1,1,0 },
        { 0,1,0,0,1,1 },
        { 0,1,1,1,1,0 },
        { 0,1,0,0,0,0 },
    };
    initMap(tmp);
    printMap();
    Position entry = { 5,1 };
    printf("************************栈思路*********************\n");
    passMaze(map, entry, &path);
    printMap();
    printf("走出路径:");
    printStack(&path);
    printf("************************递归思路*********************\n");
    init(&path);
    initMap(tmp);
    int ret = passMazeR(map, entry, entry, &path);
    printMap();
    printf("走出路径:"); 
    printStack(&path);
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325899297&siteId=291194637