深度优先搜索DFS-C语言实现、思路/解析-简笔

  • 简介
  • 基本模型-通用套路
  • 走迷宫-应用深度优先搜索
    • 思路
  • 实现
  • 执行结果

简介

深度优先搜索Depth First Search是对图论问题的分析解决,其核心思想就是就是解决1、当下应该如何做;2、下一步如何做与现在这一步如何做是一样的;3、边界条件的判断;

基本模型-通用套路

void dfs(step)
{
    /*1.判断边界,判断本阶段的DFS是否已经结束了*/
    if(foo == bar){
        /*Do something*/
        return ;
    }
    /*2.尝试每一种可能,类似于走迷宫中的在每一个点尝试每个方向*/
    for(i=0;i<_MAX_;++i)
    {
        do_something();
        dfs(step+1);//进行下一步
        undo_something();
    }
    return ;
}

走迷宫-应用深度优先搜索

思路:

  1. 确定深度探索的方向:迷宫为二维数组,每个点最多只有上下左右四个方向,因此使用一个4元素的二维数组来表示探索方向,同时对每个点增加迷宫越界判断/障碍物判断(迷宫内有障碍物)
  2. DFS的边界条件即为找到了终点(当前坐标等于终点坐标)

实现

/*2017-9-15 19:32:57
project:Depth First Search(DFS)
author:zhy
IDE:VSCode
Compile:gcc -v 4.8.1
*/

#include
#include

#define _MAX_X 5
#define _MAX_Y 4

/*绘制迷宫的函数*/
int draw();

int arr[_MAX_X][_MAX_Y]={0};    //迷宫图
int endx=3,endy=2;              //目的地
int startx=0,starty=0;          //起点
int stop[][2]={{0,2},{2,2},{
            3,1},{4,3}};        //障碍物
int num=1;
int min=-1;
int next_step[][2]={{0,1},{1,0},{0,-1},{-1,0}};   //上下左右四个方向的移动方向

void dfs(int x,int y,int step)
{
    int nextx=0,nexty=0;        //下一步的坐标
    int i=0,j=0;
    arr[0][0]=-1;       //标记原点为障碍,防止深度搜索时回溯

    if(x > _MAX_X || y > _MAX_Y || x < 0 || y < 0){
        return ;
    }

    //DFS第一步,边界条件判断
    if(x == endx && y == endy){    //进入if意味着DFS已经找到终点
        if(step < min || min <= 0){
            min = step;
        }
        //还原起点和终点的标记状态,以使它们能正确绘制
        arr[0][0]=-3;      
        arr[endx][endy]=-2;
        draw();     
        num=0;      
        return;
    }

    //DFS第二步,尝试所有可用的搜索办法
    for(i=0;i < sizeof(next_step)/sizeof(int)/2;++i)
    {
        //计算下一步的坐标并且判断是否越出了迷宫的边界
        nextx = x + next_step[i][0];
        nexty = y + next_step[i][1];
        if(nextx >= _MAX_X || nexty >= _MAX_Y || nextx < 0 || nexty < 0){
            continue;
        }

        //判断该点是否已经在路径中(即是否已经走过了,不能再往回走)或是否为障碍物
        if((arr[nextx][nexty] != -1) && (arr[nextx][nexty] <= 0)){
            arr[nextx][nexty]=num++;     //该点可走,走过该点并标记它为‘走过了’
            dfs(nextx,nexty,step+1);     //进入下一级深度继续搜索
            arr[nextx][nexty]=0;         //从上一行的dfs返回,将它还原为未走状态
        }
    }
    return;
}

int main(int argc,char *argv[])
{
    int i=0,j=0;
    int step=0;        //记录最短路径的步数

    //为障碍物、起点终点等对应的数组元素赋值
    for(i=0;i < sizeof(stop)/sizeof(int)/2;++i){
        arr[stop[i][0]][stop[i][1]] = -1;            //障碍物
    }
    arr[endx][endy]=-2;                              //目的地
    arr[startx][starty]=-3;                         //出发点

    draw();
    dfs(startx,starty,step);

    return 0;
}

int draw()
{
    int i,j;

    //打印迷宫图
    putchar('\n');
    for(i=0;i<_MAX_X;++i){
        for(j=0;j<_MAX_Y;++j)
        {
            switch(arr[i][j]){
                case 0:
                    printf("_");
                    break;
                case -1:
                    printf("X");
                    break;
                case -2:
                    printf("O");
                    break;
                case -3:
                    printf("S");
                    break;
                default:
                    printf("%d",arr[i][j]);
                    break;
            }
            printf("|");
        }
        printf("\n");
    }
    putchar('\n');
}

执行结果

深度优先搜索DFS-C语言实现、思路/解析-简笔_第1张图片

你可能感兴趣的:(C语言,算法与数据结构,算法,深度优先搜索,c语言)