• 深度优先搜索


    深度优先搜索也称深度寻路 

    规则:沿一个方向行走,走到了岔路口有选择一个方向进行前进 若碰到死胡同 退到上一个岔路口重新选择方向 走过的路不会再走 一次只能走一个点

    1.准备地图(二维数组 用1表示障碍 不可通行 用0表示可以通行

     1 #define MAP_ROW 10 2 #define MAP_COL 10 

    2.准备方向

     1 enum Path_Dir{p_up,p_down,p_left,p_right}; 

    3.准备一个栈用来保存搜索中可以行走的路径点信息

     1 #pragma one
     2 template<typename T>
     3 class CMyStack
     4 {
     5     T *pBuff;
     6     size_t len;
     7     size_t maxSize;
     8 public:
     9     CMyStack();
    10     ~CMyStack();
    11     void clear();
    12 public:
    13     void push(T const& elem);
    14     void pop();
    15     T const& getTop() const{ return pBuff[len - 1]; }
    16     bool empty() const{ return len == 0; }
    17 };
    18 
    19 template<typename T>
    20 void CMyStack<T>::pop()
    21 {
    22     --len;
    23 }
    24 
    25 template<typename T>
    26 void CMyStack<T>::push(T const& elem)
    27 {
    28     if (len>=maxSize)
    29     {
    30         maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
    31         T *tempBuff = new T[maxSize];
    32         for (size_t i = 0; i < len; i++)
    33             tempBuff[i] = pBuff[i];
    34         if (pBuff != nullptr)
    35             delete[] pBuff;
    36         pBuff = tempBuff;
    37     }
    38     pBuff[len++] = elem;
    39 }
    40 
    41 template<typename T>
    42 void CMyStack<T>::clear()
    43 {
    44     if (pBuff!=nullptr)
    45     {
    46         delete[] pBuff;
    47         pBuff = nullptr;
    48         len = maxSize = 0;
    49     }
    50 }
    51 
    52 
    53 template<typename T>
    54 CMyStack<T>::~CMyStack()
    55 {
    56     clear();
    57 }
    58 
    59 template<typename T>
    60 CMyStack<T>::CMyStack()
    61 {
    62     pBuff = nullptr;
    63     len = maxSize = 0;
    64 }

    4.准备一个结构用来保存每一个路径点再二维数组的行列值

     1 struct MyPoint 2 { 3 int row, col; 4 }; 

    5.准备一个辅助数组(1.资源地图数组不能变 2.对资源地图要进行数组标记)

    1 struct PathNode
    2 {
    3     int val;//保存原始资源的路径点信息
    4     Path_Dir dir;//当前路径点的方向标记
    5     bool isFind;//当前路径点是否被访问过
    6 };

    准备一个函数 用来判断参数坐标是否可以通行

    1 bool IsMove(PathNode p[][MAP_COL],int row,int col)
    2 {
    3     if (row < 0 || row >= MAP_ROW || col < 0 || col >= MAP_COL)
    4         return false;//如果越界,不需要进行位置的判断
    5     if (p[row][col].val != 0 || p[row][col].isFind == true)
    6         return false;//表示当前行列的元素要么是障碍,要么已经被访问过,不能通行
    7     return true;
    8 }

    第六步设置访问结点

     1     PathNode pathArr[MAP_ROW][MAP_COL];
     2     for (int i = 0; i < MAP_ROW; ++i)
     3     {
     4         for (int j = 0; j < MAP_COL; ++j)
     5         {
     6             pathArr[i][j].val = mapArr[i][j];
     7             pathArr[i][j].isFind = false;//表示地图中的每一个节点都没有被访问过
     8             pathArr[i][j].dir = p_up;//表示给地图中的每一个节点都设定一个初始方向
     9         }
    10     }

    第七步设置起点和终点

     1 MyPoint beginPoint = { 1, 1 }; 2 MyPoint endPoint = { 8, 8 }; 

    第八步准备一个容器 来保存可通行路径

    CMyStack<MyPoint> ms;
        ms.push(beginPoint);//把起点压入到容器中,用来查找后续的结点

    第九步准备一个辅助坐标点 帮助来判断下一个可通行位置

     1 MyPoint NearPoint = beginPoint;//辅助点先为起点,然后通过起点设定的方向来对周边路径进行搜索 

    第十步开始寻路

     1 while (true)//无法确定循环次数
     2     {
     3         switch (pathArr[NearPoint.row][NearPoint.col].dir)//判断当前起点在辅助数组中设定的方向
     4         {
     5         case p_up:
     6             //if (pathArr[NearPoint.row - 1][NearPoint.col].val == 0 &&    //表示当前点的上一行位置是可通行的
     7             //    pathArr[NearPoint.row - 1][NearPoint.col].isFind == false)//表示当前点的上一行位置是没有访问的
     8             pathArr[NearPoint.row][NearPoint.col].dir = p_left;//当前路口的下一个方向标记出来
     9             if (IsMove(pathArr, NearPoint.row - 1, NearPoint.col))
    10             {
    11                 //表示当前坐标的上方向能通行
    12                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    13                 MyPoint temp = { NearPoint.row - 1, NearPoint.col };
    14                 ms.push(temp);//压入这个坐标
    15                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    16             }
    17             break;
    18         case p_left:
    19             pathArr[NearPoint.row][NearPoint.col].dir = p_down;//当前路口的下一个方向标记出来
    20             if (IsMove(pathArr, NearPoint.row, NearPoint.col - 1))
    21             {
    22                 //表示当前坐标的上方向能通行
    23                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    24                 MyPoint temp = { NearPoint.row, NearPoint.col - 1 };
    25                 ms.push(temp);//压入这个坐标
    26                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    27             }
    28             break;
    29         case p_down:
    30             pathArr[NearPoint.row][NearPoint.col].dir = p_right;//当前路口的下一个方向标记出来
    31             if (IsMove(pathArr, NearPoint.row + 1, NearPoint.col))
    32             {
    33                 //表示当前坐标的上方向能通行
    34                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    35                 MyPoint temp = { NearPoint.row + 1, NearPoint.col };
    36                 ms.push(temp);//压入这个坐标
    37                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    38             }
    39             break;
    40         case p_right://最后一个方向,表示前面三个方向已经搜索完成
    41             if (IsMove(pathArr, NearPoint.row, NearPoint.col + 1))
    42             {
    43                 //表示当前坐标的上方向能通行
    44                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    45                 MyPoint temp = { NearPoint.row, NearPoint.col + 1};
    46                 ms.push(temp);//压入这个坐标
    47                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    48             }
    49             else
    50             {
    51                 //表示当前路口所有方向都不通,要准备退栈
    52                 MyPoint tempPoint = ms.getTop();//得到退栈之前的栈顶元素
    53                 pathArr[tempPoint.row][tempPoint.col].isFind = true;//要退出栈的这个元素也是已经访问过了
    54                 ms.pop();
    55                 if (!ms.empty())//如果栈不为空
    56                     NearPoint = ms.getTop();//得到新的栈顶元素
    57             }
    58             break;
    59         }
    60 
    61         if (NearPoint.row ==  endPoint.row && NearPoint.col == endPoint.col)
    62             break;//找到终点
    63         if (ms.empty())
    64             break;//没有终点
    65     }
    66 
    67     while (!ms.empty())
    68     {
    69         MyPoint tempPoint = ms.getTop();
    70         printf("row = %d, col = %d
    ",tempPoint.row,tempPoint.col);
    71         ms.pop();
    72     }

    总体代码

     1 #pragma one
     2 template<typename T>
     3 class CMyStack
     4 {
     5     T *pBuff;
     6     size_t len;
     7     size_t maxSize;
     8 public:
     9     CMyStack();
    10     ~CMyStack();
    11     void clear();
    12 public:
    13     void push(T const& elem);
    14     void pop();
    15     T const& getTop() const{ return pBuff[len - 1]; }
    16     bool empty() const{ return len == 0; }
    17 };
    18 
    19 template<typename T>
    20 void CMyStack<T>::pop()
    21 {
    22     --len;
    23 }
    24 
    25 template<typename T>
    26 void CMyStack<T>::push(T const& elem)
    27 {
    28     if (len>=maxSize)
    29     {
    30         maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
    31         T *tempBuff = new T[maxSize];
    32         for (size_t i = 0; i < len; i++)
    33             tempBuff[i] = pBuff[i];
    34         if (pBuff != nullptr)
    35             delete[] pBuff;
    36         pBuff = tempBuff;
    37     }
    38     pBuff[len++] = elem;
    39 }
    40 
    41 template<typename T>
    42 void CMyStack<T>::clear()
    43 {
    44     if (pBuff!=nullptr)
    45     {
    46         delete[] pBuff;
    47         pBuff = nullptr;
    48         len = maxSize = 0;
    49     }
    50 }
    51 
    52 
    53 template<typename T>
    54 CMyStack<T>::~CMyStack()
    55 {
    56     clear();
    57 }
    58 
    59 template<typename T>
    60 CMyStack<T>::CMyStack()
    61 {
    62     pBuff = nullptr;
    63     len = maxSize = 0;
    64 }
    MyStack.h
      1 //深度优先搜索.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "MyStack.h"
      6 
      7 //深度优先搜索
      8 
      9 //作业:1、在示例中方向顺序为上,左,下,右,如果更换这个方向顺序会有什么影响?
     10 //        2、深度寻路在有路的情况下,不一定能找到路,为什么?
     11 
     12 //规则:沿一个方向进行行走,到了岔路口又一次选择一个方向进行前进,如果碰到死胡同退回到上一个岔路口重新选择方向
     13 //        走过的路不会再走,一次走一个节点
     14 
     15 //1、准备地图 (二维数组,用1表示是障碍,不可通行,用0表示可以通行)
     16 #define MAP_ROW 10
     17 #define MAP_COL 10
     18 
     19 //2、准备方向
     20 enum Path_Dir{ p_up, p_down,p_left,p_right };
     21 
     22 //3、准备一个栈,用来保存搜索过程中可以行走的路径点信息(在规划中有后进的先出)
     23 
     24 //4、准备一个结构,用来保存每一个路径点在二维数组的行列值
     25 struct MyPoint
     26 {
     27     int row, col;
     28 };
     29 
     30 //5、准备一个辅助数组(1、资源地图数组不能变;2、对资源地图要进数据标记)
     31 struct PathNode
     32 {
     33     int val;//保存原始资源的路径点信息
     34     Path_Dir dir;//当前路径点的方向标记
     35     bool isFind;//当前路径点是否被访问过
     36 };
     37 
     38 //准备一个函数,用来判断参数的坐标是否可以通行
     39 bool IsMove(PathNode p[][MAP_COL],int row,int col)
     40 {
     41     if (row < 0 || row >= MAP_ROW || col < 0 || col >= MAP_COL)
     42         return false;//如果越界,不需要进行位置的判断
     43     if (p[row][col].val != 0 || p[row][col].isFind == true)
     44         return false;//表示当前行列的元素要么是障碍,要么已经被访问过,不能通行
     45     return true;
     46 }
     47 
     48 
     49 int _tmain(int argc, _TCHAR* argv[])
     50 {
     51     int mapArr[MAP_ROW][MAP_COL] = {
     52         { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     53         { 1, 0, 0, 1, 1, 0, 0, 0, 1, 1 },
     54         { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
     55         { 1, 1, 0, 0, 0, 0, 1, 0, 1, 1 },
     56         { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
     57         { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
     58         { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
     59         { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
     60         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
     61         { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
     62     };
     63 
     64     //第6步
     65     PathNode pathArr[MAP_ROW][MAP_COL];
     66     for (int i = 0; i < MAP_ROW; ++i)
     67     {
     68         for (int j = 0; j < MAP_COL; ++j)
     69         {
     70             pathArr[i][j].val = mapArr[i][j];
     71             pathArr[i][j].isFind = false;//表示地图中的每一个节点都没有被访问过
     72             pathArr[i][j].dir = p_up;//表示给地图中的每一个节点都设定一个初始方向
     73         }
     74     }
     75 
     76     //第7步
     77     MyPoint beginPoint = { 1, 1 };
     78     MyPoint endPoint = { 8, 8 };
     79 
     80     //第8步:准备一个容器,用来保存可通行路径点
     81     CMyStack<MyPoint> ms;
     82     ms.push(beginPoint);//把起点压入到容器中,用来查找后续的结点
     83 
     84     //第9步:准备一个辅助坐标点,帮助来判断下一个可通行位置
     85     MyPoint NearPoint = beginPoint;//辅助点先为起点,然后通过起点设定的方向来对周边路径进行搜索
     86 
     87     //第10步:开始寻路
     88     while (true)//无法确定循环次数
     89     {
     90         switch (pathArr[NearPoint.row][NearPoint.col].dir)//判断当前起点在辅助数组中设定的方向
     91         {
     92         case p_up:
     93             //if (pathArr[NearPoint.row - 1][NearPoint.col].val == 0 &&    //表示当前点的上一行位置是可通行的
     94             //    pathArr[NearPoint.row - 1][NearPoint.col].isFind == false)//表示当前点的上一行位置是没有访问的
     95             pathArr[NearPoint.row][NearPoint.col].dir = p_left;//当前路口的下一个方向标记出来
     96             if (IsMove(pathArr, NearPoint.row - 1, NearPoint.col))
     97             {
     98                 //表示当前坐标的上方向能通行
     99                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    100                 MyPoint temp = { NearPoint.row - 1, NearPoint.col };
    101                 ms.push(temp);//压入这个坐标
    102                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    103             }
    104             break;
    105         case p_left:
    106             pathArr[NearPoint.row][NearPoint.col].dir = p_down;//当前路口的下一个方向标记出来
    107             if (IsMove(pathArr, NearPoint.row, NearPoint.col - 1))
    108             {
    109                 //表示当前坐标的上方向能通行
    110                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    111                 MyPoint temp = { NearPoint.row, NearPoint.col - 1 };
    112                 ms.push(temp);//压入这个坐标
    113                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    114             }
    115             break;
    116         case p_down:
    117             pathArr[NearPoint.row][NearPoint.col].dir = p_right;//当前路口的下一个方向标记出来
    118             if (IsMove(pathArr, NearPoint.row + 1, NearPoint.col))
    119             {
    120                 //表示当前坐标的上方向能通行
    121                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    122                 MyPoint temp = { NearPoint.row + 1, NearPoint.col };
    123                 ms.push(temp);//压入这个坐标
    124                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    125             }
    126             break;
    127         case p_right://最后一个方向,表示前面三个方向已经搜索完成
    128             if (IsMove(pathArr, NearPoint.row, NearPoint.col + 1))
    129             {
    130                 //表示当前坐标的上方向能通行
    131                 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
    132                 MyPoint temp = { NearPoint.row, NearPoint.col + 1 };
    133                 ms.push(temp);//压入这个坐标
    134                 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
    135             }
    136             else
    137             {
    138                 //表示当前路口所有方向都不通,要准备退栈
    139                 MyPoint tempPoint = ms.getTop();//得到退栈之前的栈顶元素
    140                 pathArr[tempPoint.row][tempPoint.col].isFind = true;//要退出栈的这个元素也是已经访问过了
    141                 ms.pop();
    142                 if (!ms.empty())//如果栈不为空
    143                     NearPoint = ms.getTop();//得到新的栈顶元素
    144             }
    145             break;
    146         }
    147 
    148         if (NearPoint.row == endPoint.row && NearPoint.col == endPoint.col)
    149             break;//找到终点
    150         if (ms.empty())
    151             break;//没有终点
    152     }
    153 
    154     while (!ms.empty())
    155     {
    156         MyPoint tempPoint = ms.getTop();
    157         printf("row = %d, col = %d
    ", tempPoint.row, tempPoint.col);
    158         ms.pop();
    159     }
    160     return 0;
    161 }
    深度优先搜索.cpp
  • 相关阅读:
    小项目心得交流
    自己写的web标准教程,帮你走进web标准设计的世界——第三讲(html终结篇)
    css之清除区域
    面向对象大作业(自主选题)
    关于vue在hash模式偶发不能后退的处理
    flex布局设置单个子元素靠右
    css 选择器
    Git常用命令及方法大全
    解决微信sdk之uploadImage上传多张图片时循环提示“上传中”
    grid 布局
  • 原文地址:https://www.cnblogs.com/liugangjiayou/p/11462783.html
Copyright © 2020-2023  润新知