• 迷宫——BFS(最短路径和所有路径)


    对于图这种数据结构,最基础的就是它的遍历方式。

    在书上看到一段话:对于无权的图,使用广搜就可以获得其路径,对于有权图就不可以。

    无权的图,就相当于每条边的权为1。迷宫就是最简单的一种无权图,每一步都是一个节点,节点和节点之间的边长都为1。

    为了验证这个思想,自己定义一个迷宫,通过BFS获得可以走出去的所有路径和最短的路径。

    BFS就是以一个起点,配合队列,向四面八方进行搜索,搜过过了就更改标记表示已经走过了。

     1 #include <iostream>
     2 #include <fstream>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <string>
     6 #include <list>
     7 #include <stack>
     8 #include <queue>
     9 
    10 using namespace std;
    11 
    12 typedef struct point{
    13     int x;
    14     int y;
    15     point *previous;
    16     int step;
    17 } point;
    18 
    19 point dir[4] = {
    20     { 0, 1, NULL, 0 },
    21     { 1, 0, NULL, 0 },
    22     { 0, -1, NULL, 0 },
    23     { -1, 0, NULL, 0 },
    24 };
    25 
    26 //只有0位置可以走,到数组边缘就是走出迷宫。
    27 //输出最短的路径和最短步数
    28 int map[8][8] = {
    29     { 1, 0, 1, 1, 1, 1, 1, 1 },
    30     { 1, 0, 0, 0, 0, 0, 0, 1 },
    31     { 1, 0, 1, 1, 1, 1, 0, 1 },
    32     { 1, 0, 0, 0, 0, 1, 0, 0 },
    33     { 1, 1, 1, 1, 0, 0, 1, 1 },
    34     { 1, 1, 1, 1, 1, 0, 1, 1 },
    35     { 1, 1, 0, 0, 0, 0, 1, 1 },
    36     { 1, 1, 0, 1, 1, 1, 1, 1 },
    37 };
    38 
    39 void PrintAllPath(point *p)
    40 {
    41     int shortest = p->step;
    42     
    43     cout << "可行短路径为:";
    44     while (p->previous != NULL)
    45     {
    46         cout << "(" << p->x << "," << p->y << ")";
    47         p = p->previous;
    48     }
    49     cout << "(" << p->x << "," << p->y << ")" << endl;
    50     cout << "路径长度为:" << shortest << endl;
    51 }
    52 
    53 void BFS(point startPoint)
    54 {
    55     queue<point> q;
    56     q.push(startPoint);
    57     point cur;
    58 
    59     while (!q.empty())
    60     {
    61         cur = q.front();
    62         q.pop();
    63         map[cur.x][cur.y] = 1;
    64 
    65         for (int i = 0; i < 4; i++)
    66         {
    67             point nxt{ cur.x + dir[i].x, cur.y + dir[i].y, NULL, 0 };
    68             if (nxt.x >= 0 && nxt.x < 8 && nxt.y >= 0 && nxt.y < 8 && map[nxt.x][nxt.y] == 0)
    69             {
    70                 point *tmp = new point;
    71                 memcpy(tmp, &cur, sizeof(point));
    72                 nxt.previous = tmp;
    73                 nxt.step = cur.step + 1;
    74                 map[nxt.x][nxt.y] = 1;
    75 
    76                 if (nxt.x == 0 || nxt.x == 7 || nxt.y == 0 || nxt.y == 7)
    77                 {
    78                     PrintAllPath(&nxt);
    79 
    80                     //这句话注释则输出所有路径,不注释是最短路径
    81                     //return;
    82                 }
    83                 q.push(nxt);
    84             }
    85         }
    86     }
    87 }
    88 
    89 int main()
    90 {
    91     point startPoint{ 0, 1, NULL, 0 };
    92     BFS(startPoint);
    93 
    94     return 0;
    95 }
    View Code

    结果,上图:

    广搜很好实现。在设计点坐标时,需要几个参量:

    x,y;

    上一个节点x,y;

    已经走的步数。

    配合这个左边点数据结构不断进入队列,当此节点碰到边界时则走出去,函数返回则是最短路径。

    不return,则会输出所有的路径和步数。

  • 相关阅读:
    如何在Eclipse中显示行号
    最值得听的100首英文歌
    ffmpeg示例一:源码
    编码解码中常用术语二
    ffmpeg.c(ffmpeg.exe)调试笔记一
    Debug ffmpeg.c & ffmpeg_g.exe in Ubuntu with Eclipse
    ubuntu下编译ffmpeg with libx264
    利用ffmpeg切割与合并视频(一)调用ffmpeg程序直接切割
    VMWare安装Ubuntu 12.10无法开启虚拟机的Unity Mode模式
    Atitit.基于dsl的methodinvoker
  • 原文地址:https://www.cnblogs.com/wyc199288/p/6655605.html
Copyright © 2020-2023  润新知