多个出口的迷宫,求最短路径

//stack.h
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stddef.h>

typedef struct point
{
    int row;
    int col;
}point;

#define SEQ_STACK_SIZE 100

typedef struct SeqStack
{
    point date[SEQ_STACK_SIZE];
    size_t size;
}SeqStack;

void SeqStackInit(SeqStack* stack);

void SeqStackDestory(SeqStack* stack);

void SeqStackPush(SeqStack* stack, point value);

void SeqStackPop(SeqStack* stack);

int SeqStackTop(SeqStack* stack, point* value);

void StackPrintf(SeqStack* stack);

int SeqStackSize(SeqStack* stack);

void SeqStackRplace(SeqStack* from, SeqStack* to);
//stack.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"stack.h"

///////////////////////////////////
//        栈的初始化             //
///////////////////////////////////
void SeqStackInit(SeqStack* stack)
{
    if (stack == NULL)
    {
        return;
    }
    stack->size = 0;
}

///////////////////////////////////
//        栈的销毁               //
///////////////////////////////////
void SeqStackDestory(SeqStack* stack)
{
    if (stack == NULL)
    {
        return;
    }
    stack->size = 0;
}

///////////////////////////////////
//           压栈                //
///////////////////////////////////
void SeqStackPush(SeqStack* stack, point value)
{
    if (stack == NULL)
    {
        return;
    }
    if (stack->size > SEQ_STACK_SIZE - 1)
    {
        return;
    }
    stack->date[stack->size++] = value;
}


///////////////////////////////////
//           出栈                //
///////////////////////////////////
void SeqStackPop(SeqStack* stack)
{
    if (stack == NULL)
    {
        return;
    }
    if (stack->size == 0)
    {
        printf("栈为空\n");
        return;
    }
    stack->size = stack->size - 1;
}

///////////////////////////////////
//           取栈顶元素         //
///////////////////////////////////
int SeqStackTop(SeqStack* stack, point* value)
{
    if (stack == NULL)
    {
        return 0;
    }
    if (stack->size == 0)
    {
        printf("栈为空\n");
        return 0;
    }
    *value = stack->date[stack->size - 1];
    return 1;
}

///////////////////////////////////
//          栈的长度             //
///////////////////////////////////
int SeqStackSize(SeqStack* stack)
{
    if (stack == NULL)
    {
        return -1;
    }
    return stack->size;
}

///////////////////////////////////
//          替换栈               //
///////////////////////////////////
void SeqStackRplace(SeqStack* from, SeqStack* to)
{
    if (from == NULL || to == NULL)
    {
        return;
    }
    SeqStackDestory(to);
    size_t i = 0;
    for (i = 0; i < from->size; ++i)
    {
        to->date[to->size++] = from->date[i];
    }
}

///////////////////////////////////
//           打印栈              //
///////////////////////////////////
void StackPrintf(SeqStack* stack)
{
    printf("[栈底]");
    printf("\n");
    size_t i = 0;
    for (i = 0; i < (stack->size); ++i)
    {
        printf(" (%d, %d) ", stack->date[i].row,stack->date[i].col);
        printf("\n");
    }
    printf("[栈顶]\n");
}
//递归的方法求最短路径
#include<stdio.h>
#include<stdlib.h>
#include"stack.h"

#define MAZE_ROW 6
#define MAZE_COL 6

typedef struct Maze
{
    int map[MAZE_ROW][MAZE_COL];
}Maze;

void MazeInit(Maze* maze)
{
    int map[MAZE_ROW][MAZE_COL] =
    {
        { 0,1,0,0,0,0 },
        { 0,1,1,1,0,0 },
        { 0,1,0,1,1,1 },
        { 0,1,1,1,0,0 },
        { 0,1,0,1,1,0 },
        { 0,1,0,0,1,0 }
    };
    int i = 0;
    int j = 0;
    for (i = 0; i<MAZE_ROW; ++i)
        for (j = 0; j<MAZE_COL; ++j)
        {
            maze->map[i][j] = map[i][j];
        }
}

void MazePrint(Maze *maze)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < MAZE_ROW; ++i)
    {
        for (j = 0; j < MAZE_COL; ++j)

        {
            printf("%2d ", maze->map[i][j]);
        }
        printf("\n");
    }
}

//判断是不是落脚点
int Is_Stay(Maze *maze, point pos)
{
    if (pos.row < 0 || pos.row > MAZE_ROW - 1
        || pos.col < 0 || pos.col > MAZE_COL - 1
        || maze->map[pos.row][pos.col] != 1)
        return 0;
    else
        return 1;
}



int Is_Chukou(point pos, point entry)
{
    if ((pos.row == 0) || (pos.row == MAZE_ROW - 1)
        || (pos.col == 0) || (pos.col == MAZE_COL - 1))
    {
        if (pos.row == entry.row  && pos.col == entry.col)
            return 0;
        else
            return 1;
    }
    return 0;

}

int Is_Stay_Wirh_Cirl(Maze* maze, point cur, point pre)
{
    if (pre.row < 0 || pre.col < 0)
    {
        //如果之前的点非法,也就是当前点是第一个点,那我们直接判断cur是否能落脚
        if (cur.row < 0 || cur.row > MAZE_ROW - 1
            || cur.col < 0 || cur.col > MAZE_COL - 1 && maze->map[cur.row][cur.col] == 0)
            return 0;
        else
            return 1;
    }
    else
    {
        //1.判断当前点是否在地图上
        if (cur.row < 0 || cur.row > MAZE_ROW - 1
            || cur.col < 0 || cur.col > MAZE_COL - 1)
            return 0;
        //2.判断当前点的值是否为1,如果是1,一定能落脚
        if(maze->map[cur.row][cur.col] == 0)
            return 0;
        if (maze->map[cur.row][cur.col] == 1)
            return 1;
        //判断当前点的值和前一个点值的大小   当前点的值 - 1  <   之前的值,就可以落脚
        if (maze->map[cur.row][cur.col] > maze->map[pre.row][pre.col] + 1)
        {
            return 1;
        }
    }
    return 0;
}

void Mark_With_Cirl(Maze* maze, point cur,point pre)
{

    if (pre.row < 0 || pre.col < 0)
    {
        maze->map[cur.row][cur.col] ++;
    }
    else

    maze->map[cur.row][cur.col] = maze->map[pre.row][pre.col] + 1;
}

void _GetShort_pathWith_Cirl(Maze* maze, point cur, point pre, point entry, SeqStack* cur_path, SeqStack* short_path)
{
    if (cur_path == NULL || short_path == NULL)
    {
        return;
    }
    //1.判断当前点是否能落脚
    if (!(Is_Stay_Wirh_Cirl(maze, cur, pre)))
    {
        return;
    }
    //2.标记当前点,并push到cur_path,

    Mark_With_Cirl(maze, cur,pre);
    SeqStackPush(cur_path, cur);
    //3.判断当前点是不是出口,如果是出口,比较cur_push和short_path的长度
    //a. 如果cur_push比short_path短,或者short_path为空,用cur_path替换short_path
    if (Is_Chukou(cur, entry))
    {
        //a)比较当前的cur_path和short_path的长短
        //b)如果cur_path比short_path小  或者   short_path为空
        if (SeqStackSize(cur_path) < SeqStackSize(short_path) || SeqStackSize(short_path) == 0)
        {
            //用cur_path替换short_path
            SeqStackRplace(cur_path, short_path);
        }

        printf("找到一条路径:\n");
        StackPrintf(cur_path);
        printf("当前最短路径为:\n");
        StackPrintf(short_path);
        //c)让cur_path出栈,返回到上一层栈帧
        SeqStackPop(cur_path);
        return;
    }
    //4.按照一定的顺序,递归的调用该函数,完成领节点的判断
    point up = cur;
    up.row -= 1;
    _GetShort_pathWith_Cirl(maze,  up, cur, entry, cur_path, short_path);

    point right = cur;
    right.col += 1;
    _GetShort_pathWith_Cirl(maze,  right, cur ,entry, cur_path, short_path);

    point down = cur;
    down.row += 1;
    _GetShort_pathWith_Cirl(maze,  down, cur, entry, cur_path, short_path);

    point left = cur;
    left.col -= 1;
    _GetShort_pathWith_Cirl(maze,   left, cur, entry, cur_path, short_path);

    //5.cur_path出栈,回溯到上一个位置 
    SeqStackPop(cur_path);
    return;


}

void GetShort_pashWith_Cirl(Maze *maze, point entry)
{
    if (maze == NULL)
    {
        return;
    }
    if (!Is_Stay(maze, entry))
    {
        return;
    }
    SeqStack short_path;
    SeqStackInit(&short_path);
    SeqStack cur_path;
    SeqStackInit(&cur_path);
    point cur = entry;
    point pre = { -1,-1 };
    _GetShort_pathWith_Cirl(maze, cur, pre, entry, &cur_path, &short_path);
    printf("最终的最短路径为:\n");
    StackPrintf(&short_path);

}

void TestInit()
{
    Maze maze;
    MazeInit(&maze);
    MazePrint(&maze);
}
void Test()
{
    Maze maze;
    MazeInit(&maze);
    MazePrint(&maze);
    point pos = { 0,1 };
    //GetShort_pash(&maze, pos);
    GetShort_pashWith_Cirl(&maze, pos);
    MazePrint(&maze);
}

int main()
{
    //TestInit();
    Test();
    system("pause");
    return 0;
}



//循环的方法求最短路径
#include<stdio.h>
#include<stdlib.h>
#include"stack.h"

#define MAZE_ROW 6
#define MAZE_COL 6

typedef struct Maze
{
    int map[MAZE_ROW][MAZE_COL];
}Maze;

void MazeInit(Maze* maze)
{
    int map[MAZE_ROW][MAZE_COL] =
    {
        { 0,1,0,0,0,0 },
        { 0,1,1,1,0,0 },
        { 0,1,0,1,1,1 },
        { 0,1,1,1,0,0 },
        { 0,1,0,1,1,0 },
        { 0,1,0,0,1,0 }
    };
    int i = 0;
    int j = 0;
    for (i = 0; i<MAZE_ROW; ++i)
        for (j = 0; j<MAZE_COL; ++j)
        {
            maze->map[i][j] = map[i][j];
        }
}

void MazePrint(Maze *maze)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < MAZE_ROW; ++i)
    {
        for (j = 0; j < MAZE_COL; ++j)

        {
            printf("%2d ", maze->map[i][j]);
        }
        printf("\n");
    }
}

//判断是不是落脚点
int Is_Stay(Maze *maze, point pos)
{
    if (pos.row < 0 || pos.row > MAZE_ROW - 1
        || pos.col < 0 || pos.col > MAZE_COL - 1
        || maze->map[pos.row][pos.col] != 1)
        return 0;
    else
        return 1;
}



int Is_Chukou(point pos, point entry)
{
    if ((pos.row == 0) || (pos.row == MAZE_ROW - 1)
        || (pos.col == 0) || (pos.col == MAZE_COL - 1))
    {
        if (pos.row == entry.row  && pos.col == entry.col)
            return 0;
        else
            return 1;
    }
    return 0;

}

int Is_Stay_Wirh_Cirl(Maze* maze, point cur, point pre)
{
    if (pre.row < 0 || pre.col < 0)
    {
        //如果之前的点非法,也就是当前点是第一个点,那我们直接判断cur是否能落脚
        if (cur.row < 0 || cur.row > MAZE_ROW - 1
            || cur.col < 0 || cur.col > MAZE_COL - 1 && maze->map[cur.row][cur.col] == 0)
            return 0;
        else
            return 1;
    }
    else
    {
        //1.判断当前点是否在地图上
        if (cur.row < 0 || cur.row > MAZE_ROW - 1
            || cur.col < 0 || cur.col > MAZE_COL - 1)
            return 0;
        //2.判断当前点的值是否为1,如果是1,一定能落脚
        if (maze->map[cur.row][cur.col] == 0)
            return 0;
        if (maze->map[cur.row][cur.col] == 1)
            return 1;
        //判断当前点的值和前一个点值的大小   当前点的值 - 1  <   之前的值,就可以落脚
        if (maze->map[cur.row][cur.col] > maze->map[pre.row][pre.col] + 1)
        {
            return 1;
        }
    }
    return 0;
}

void Mark_With_Cirl(Maze* maze, point cur, point pre)
{

    if (pre.row < 0 || pre.col < 0)
    {
        maze->map[cur.row][cur.col] ++;
    }
    else

        maze->map[cur.row][cur.col] = maze->map[pre.row][pre.col] + 1;
}

void _GetShort_pathWith_Cirl(Maze* maze, point cur, point pre, point entry, SeqStack* cur_path, SeqStack* short_path)
{
    if (cur_path == NULL || short_path == NULL)
    {
        return;
    }
    //1.入口是否能落脚
    if (!(Is_Stay_Wirh_Cirl(maze, cur, pre)))
    {
        return;
    }
    SeqStack stack;
    SeqStackInit(&stack);
    //2.标记入口点,入口点入栈 ,还要入cur_path
    Mark_With_Cirl(maze, cur, pre);
    SeqStackPush(&stack, cur);
    SeqStackPush(cur_path, cur);
    //3.进入循环,取栈顶为当前点
    while (SeqStackTop(&stack , &cur))
    {
        //4.判断当前点是不是出口,若是出口
        if ((Is_Chukou(cur, entry)))
        {
            // a)比较cur_path的长度,如果比short_path短,或者short_path为空
            //用cur_path替换short_path

            if (SeqStackSize(cur_path) < SeqStackSize(short_path) || SeqStackSize(short_path) == 0)
            {
                //用cur_path替换short_path
                SeqStackRplace(cur_path, short_path);
            }

            printf("找到一条路径:\n");
            StackPrintf(cur_path);
            printf("当前最短路径为:\n");
            StackPrintf(short_path);
            //  b)栈出栈,cur_path出栈,进行下一次循环
            SeqStackPop(&stack);
            SeqStackPop(cur_path);
            continue;
        }

        //5.按照一定的顺序判断邻节点,若邻接点能够落脚,入栈,也入cur_path,进入下一次循环
        point up = cur;
        up.row -= 1;
        if (Is_Stay_Wirh_Cirl(maze, up, cur))
        {
            Mark_With_Cirl(maze,up, cur);
            SeqStackPush(&stack, up);
            SeqStackPush(cur_path, up);
            continue;
        }

        point right = cur;
        right.col += 1;
        if (Is_Stay_Wirh_Cirl(maze, right, cur))
        {
            Mark_With_Cirl(maze, right, cur);
            SeqStackPush(&stack, right);
            SeqStackPush(cur_path, right);
            continue;
        }

        point down = cur;
        down.row += 1;
        if (Is_Stay_Wirh_Cirl(maze, down, cur))
        {
            Mark_With_Cirl(maze, down, cur);
            SeqStackPush(&stack, down);
            SeqStackPush(cur_path, down);
            continue;
        }

        point left = cur;
        left.row -= 1;
        if (Is_Stay_Wirh_Cirl(maze, left, cur))
        {
            Mark_With_Cirl(maze, left , cur);
            SeqStackPush(&stack, left);
            SeqStackPush(cur_path, left);
            continue;
        }

        //6.四周都判断完后,回溯到下一个位置,栈出栈,
        SeqStackPop(&stack);
        SeqStackPop(cur_path);
    }



}

void GetShort_pashWith_Cirl(Maze *maze, point entry)
{
    if (maze == NULL)
    {
        return;
    }
    if (!Is_Stay(maze, entry))
    {
        return;
    }
    SeqStack short_path;
    SeqStackInit(&short_path);
    SeqStack cur_path;
    SeqStackInit(&cur_path);
    point cur = entry;
    point pre = { -1,-1 };
    _GetShort_pathWith_Cirl(maze, cur, pre, entry, &cur_path, &short_path);
    printf("最终的最短路径为:\n");
    StackPrintf(&short_path);

}

void TestInit()
{
    Maze maze;
    MazeInit(&maze);
    MazePrint(&maze);
}
void Test()
{
    Maze maze;
    MazeInit(&maze);
    MazePrint(&maze);
    point pos = { 0,1 };
    //GetShort_pash(&maze, pos);
    GetShort_pashWith_Cirl(&maze, pos);
    MazePrint(&maze);
}

int main()
{
    //TestInit();
    Test();
    system("pause");
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值