【Data Structure】------- Find the shortest path of the multi-exit maze

Above we have written recursion and non-recursion to solve the problem of mazes. Today we will implement multiple paths and the shortest problem on the basis of recursion.
Initialize the shortest path map

 /////////////////////////////////////////////////
//////////////多通路最短路径/////////////////////
////////////////////////////////////////////////
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];
        }
       }
}

Use this special function to print the stack

//这个函数只用于迷宫问题,用来调试,通常意义下,我们栈不允许
//遍历的,但是如果进行测试或调试,这是个例外
//因此在这里函数虽然进行了遍历,但是仅用于调试
//之所以写这样一个函数遍历栈,为了能够从入口的顺序来打印栈中的内容
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;
}

core idea

Our idea is to try to find all the paths, and then find the shortest path from all the paths

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,"最短路径是:");

}

The test function is as follows:

void test3(){

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

Our main idea is to define two stacks, and then let one store the current path and the other store the smallest path. We compare the current path and the smallest path each time, and the small one is stored in the stack that stores the smallest path. middle.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325454990&siteId=291194637