利用图的宽度优先搜索(层次遍历)实现查找从迷宫左上


  
  // 查找从迷宫左上角到右下角的最优路径(路径最短)
  // 利用图的宽度优先搜索(层次遍历)实现
  int SearchMaze(int *A, int m, int n, vector &path)
  {
      // 迷宫位置类型
      typedef pair Position;
  
      // 移动操作类型
      typedef unsigned char MoveType;
      const MoveType UNVISITED = 'N';       // 未访问
      const MoveType START = 'S';           // 起点
      const MoveType UP = 'U';              // 向上
      const MoveType RIGHT = 'R';           // 向右
      const MoveType DOWN = 'D';            // 向下
      const MoveType LEFT = 'L';            // 向左
  
      // 用于暂存位置的队列
      queue posQueue;
  
      // 标记,用于区分层次遍历的各层,以便计算路径长度
      Position tag(-1, -1);
      // 目标位置
      Position target(m - 1, n - 1);
  
      // 状态数组,用于记录迷宫的每个位置是否已经访问
      vector state(m * n, UNVISITED);
  
      // 标记能否到达目标位置
      bool succeed = false;
  
      // 把起始位置压入队列,开始搜索
      posQueue.push(make_pair(0, 0));
      posQueue.push(tag);
      int pathLength = 1;
      state[0] = START;
     
      // 搜索目标位置
      while (!posQueue.empty()) {
          Position cur = posQueue.front();
          posQueue.pop();
  
          if (cur == target) {
              // 找到目标位置
              succeed = true;
              break;
          }
  
          if (cur == tag) {
              // 本层遍历结束,进入下一层
              if (!posQueue.empty()) {
                  ++pathLength;
                  posQueue.push(tag);
              }
              continue;
          }
  
          // 从当前位置向上、下、左、右搜索
          int i = cur.first;
          int j = cur.second;
          int index;
  
          // 向上
          index = (i - 1) * n + j;
          if (i > 0 && A[index] == 0 && state[index] == UNVISITED) {
              posQueue.push(Position(i - 1, j));
              state[index] = UP;
          }
  
          // 向右
          index = i * n + j + 1;
          if (j < n - 1 && A[index] == 0 && state[index] == UNVISITED) {
              posQueue.push(Position(i, j + 1));
              state[index] = RIGHT;
          }
  
          // 向下
          index = (i + 1) * n + j;
          if (i < m - 1 && A[index] == 0 && state[index] == UNVISITED) {
              posQueue.push(Position(i + 1, j));
              state[index] = DOWN;
          }
  
          // 向左
          index = i * n + j - 1;
          if (j > 0 && A[index] == 0 && state[index] == UNVISITED) {
              posQueue.push(Position(i, j - 1));
              state[index] = LEFT;
          }
      }
  
      if (succeed) {
          // 能够到达目标位置,输出移动操作序列
          path.clear();
          path.reserve(pathLength);
  
          int i = m - 1;
          int j = n - 1;
          int index = i * n + j;
          for (; state[index] != START; index = i * n + j) {
              assert(state[index] != UNVISITED && "不可能是未访问位置!");
              path.push_back(state[index]);
              switch (state[index])
              {
              case UP:
                  ++i;
                  break;
  
              case RIGHT:
                  --j;
                  break;
  
              case DOWN:
                  --i;
                  break;
  
              case LEFT:
                  ++j;
                  break;
              }
          }
          reverse(path.begin(), path.end());
  
          return pathLength;
      }
  
      return -1;
  }
  
  int main()
  {
      const int m = 8;
      const int n = 8;
      int A[m * n] = {
          0, 0, 0, 0, 1, 0, 0, 0,
          1, 0, 1, 0, 0, 0, 1, 0,
          0, 0, 1, 0, 1, 0, 1, 0,
          0, 1, 1, 0, 0, 0, 1, 0,
          0, 0, 0, 0, 1, 1, 0, 0,
          0, 1, 1, 0, 0, 0, 0, 1,
          0, 0, 0, 0, 1, 0, 1, 1,
          1, 0, 0, 0, 1, 0, 0, 0,
      };
  
      vector path;
  
      int length = SearchMaze(A, 8, 8, path);
  
      if (length > 0) {
          cout << "Shortest path length: " << length << endl;
          cout << "The Path: ";
          copy(path.begin(), path.end(), ostream_iterator(cout));
          cout << endl;
      } else {
          cout << "Can't reach the destination!" << endl;
      }
  
  }
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值