Solve the shortest path in a maze with loops

Solve the shortest path in a maze with loops

For the statement of Stack and Position, please refer to the previous article (stack walks a simple maze): https://blog.csdn.net/hanzheng6602/article/details/80053607

result:write picture description here

Ideas: Similar to the recursive idea above, but to solve the looping problem, you need to mark the nodes to update the shortest path.

Two stacks are used to save the path, one for the current path and the other for the minimum path. If a path is currently found, it is compared with the shortest path. If it is smaller than the shortest path, the minimum stack is updated.
write picture description here

maze function

void passMazeC(int maze[ROW][COL], Position cur, Position entry, Stack* path, Stack * min)
{
    if (!isValidEntry(maze, entry)) {
        return 0;
    }
    //标记入口点
    maze[entry.x][entry.y] = 2;
    //求解子迷宫问题
    _passMazeC(maze, cur, entry, path, min);
}

void _passMazeC(int maze[ROW][COL], Position cur, Position entry, Stack* path, Stack * min)
{
    pushBack(path, cur);
    if (isExit(maze, cur, entry)) {
        //第一次找到路径,或者更新最短路径
        if ( isEmpty(path) || (min->top > path->top)) {
            update(min, path);
        }
        pop(path);
        return;
    }
    //上右下左走
    Position tmp = cur;
    tmp.x -= 1;
    if (isValidPathC(maze, cur, tmp)) {
        maze[tmp.x][tmp.y] = maze[cur.x][cur.y] + 1;
        _passMazeC(maze, tmp, entry, path, min);
    }

    tmp = cur;
    tmp.y += 1;
    if (isValidPathC(maze, cur, tmp)) {
        maze[tmp.x][tmp.y] = maze[cur.x][cur.y] + 1;
        _passMazeC(maze, tmp, entry, path, min);
    }

    tmp = cur;
    tmp.x += 1;
    if (isValidPathC(maze, cur, tmp)) {
        maze[tmp.x][tmp.y] = maze[cur.x][cur.y] + 1;
        _passMazeC(maze, tmp, entry, path, min);
    }

    tmp = cur;
    tmp.y -= 1;
    if (isValidPathC(maze, cur, tmp)) {
        maze[tmp.x][tmp.y] = maze[cur.x][cur.y] + 1;
        _passMazeC(maze, tmp, entry, path, min);
    }
    //四个方向都走完了
    pop(path);
    return ;
}

helper function

int isValidPathC(int maze[ROW][COL], Position cur, Position next)//检查是否可以走
{
    if (next.x < 0 || next.y < 0 || next.x >= ROW || next.y >= COL) {
        return 0;
    }
    else if (maze[next.x][next.y] == 1 || ( maze[cur.x][cur.y]+1 < maze[next.x][next.y])) {
        return 1;
    }
    return 0;
}
//更新最小路径——复制栈
void update(Stack *dest, Stack *src)
{
    //销毁原栈,按src的大小给dest开辟空间
    destory(dest);
    Stack* tmp = NULL;
    tmp= (Stack*)malloc(src->capacity * sizeof(Datatype));
    if (NULL != tmp) {
        dest->array = tmp;
    }
    dest->capacity = src->capacity;
    dest->top = src->top;
    //复制内容
    int i = 0;
    for (i = 0; i < src->top; i++) {
        dest->array[i] = src->array[i];
    }
}

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;
}

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];
}

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 };
    Stack min;
    init(&min);
    passMazeC(map, entry, entry, &path, &min);
    printMap();
    printf("最短路径:");
    printStack(&min);
}

Guess you like

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