【数据结构】-------求多出口迷宫的最短路径

上面我们已经写过递归和非递归来实现求解迷宫的问题,今天我们就在递归的基础上实现多条通路,最短问题。
初始化最短路径地图

 /////////////////////////////////////////////////
//////////////多通路最短路径/////////////////////
////////////////////////////////////////////////
void MazeInitShortPath(Maze*  maze){
   int map[ROW][COL]={
       {0,1,0,0,0,0},
       {0,1,1,0,0,0},
       {0,1,0,1,1,1},
       {1,1,1,0,0,0},
       {0,0,1,0,0,0},
       {0,0,1,0,0,0},
   };
    int i = 0;
    for (; i<ROW; i++){
        int  j = 0;
        for (; j<COL; j++){
            maze->map[i][j] = map[i][j];
        }
       }
}

用这个特殊的函数来打印栈

//这个函数只用于迷宫问题,用来调试,通常意义下,我们栈不允许
//遍历的,但是如果进行测试或调试,这是个例外
//因此在这里函数虽然进行了遍历,但是仅用于调试
//之所以写这样一个函数遍历栈,为了能够从入口的顺序来打印栈中的内容
void SeqStackDebugPrint(SeqStack* stack, const char* msg){
    printf("%s\n",msg);
    if(stack==NULL){
    return;
    }
    size_t i=0;
    for(;i<stack->size;i++){
    printf("(%d,%d)\n",stack->data[i].row,stack->data[i].col);
    }
    printf("\n");
}
void SeqStackDestroy(SeqStack* stack){
     free(stack->data);
     stack->size=0;
     stack->capacity=0;
}

void _GetShortPath(Maze* maze,Point cur,Point entry,SeqStack* cur_path,SeqStack* short_path)
{
   // 1、判定当前点能否落脚
    if(!CanStay(maze,cur)){
    return;
    }
   //2、如果能落脚,就对当前点进行标记,同时把当前点插入到当前cur_path
    else
    {
    Mark(maze,cur);
    SeqStackPush(cur_path,entry);
    }
   //3、判断当前点是否出口
   if(IsExit(maze,cur,entry)){

   //a、如果当前点是出口,说明当前找到了一条路经,就拿当前路径和short_path中的路径进行比较,
   //如果当前路径比short_path短,或者short_path本身是一个空栈,
   //就用当前路径代替short_path代替完毕之后也要回溯,尝试找其他的路径
   printf("找到了一条路径\n");
   if(cur_path->size<short_path->size||short_path->size==0){
       printf("找到了一条比较短的路径\n");
   }
   SeqStackAssgin(cur_path,short_path);//栈对象赋值
   // b、如果当前路径没有比short_path短,就要尝试着去找其他路径(进行回溯)
   //在回溯之前也要把cur_path栈顶元素也进行出栈

             SeqStackPop(cur_path);
               return;
   }
  //4、如果当前点不是出口,尝试探测四个方向(按照顺时针来探测)
   Point up=cur;
   up.row-=1;
   _GetShortPath(maze,up,entry,cur_path,short_path);
   Point right=cur;
   right.col+=1;
   _GetShortPath(maze,right,entry,cur_path,short_path);
   Point down=cur;
   down.row+=1;
   _GetShortPath(maze,down,entry,cur_path,short_path);
   Point left=cur;
   left.col-=1;
   _GetShortPath(maze,left,entry,cur_path,short_path);

   // 5、如果四个方向都递归探测过了,就可以进行
   // 出栈(指当前函数栈帧结束,同时cur_path,也要进行出栈)回溯到
   //上一个点
  SeqStackPop(cur_path);
  return;
}

核心思路

我们的思路就是尝试找到所有的路径,然后从所有的路径中找到最短的路径

void  GetShortPath(Maze* maze,Point entry){
//和我们从数组中找到最小的数字的思路是一样的
//保存着当前找到的路径
   SeqStack cur_path;
   //保存着最短的路径
   SeqStack short_path;

   SeqStackInit(&cur_path);
   SeqStackInit(&short_path);
  _GetShortPath(maze,entry,entry,&cur_path,&short_path);//辅助递归的函数
   //打印栈中的内容
   SeqStackDebugPrint(&short_path,"最短路径是:");

}

测试函数如下:

void test3(){

        TEST_HEADER;
    Maze maze;
    MazeInitShortPath(&maze);
    MazePrint(&maze);
    Point entry = { 0, 1 };
    GetShortPath(&maze,entry);
    MazePrint(&maze);
}

我们的主要思路就是定义出两个栈,然后让一个存放当前的路径,一个存放的是最小的路径,我们每次用当前的路径和最小的路径进行比较,小的存放在存放最小路径的栈中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值