C语言算法:深度优先探索

来源:互联网 发布:量子隧道效应 知乎 编辑:程序博客网 时间:2024/04/29 15:23
  这是我从一本书上看的的一道题,特来与大家分享,如下:
  假设有5个城市编号为1,2,3,4,5,它们之间的关系为如图C语言算法:深度优先探索
    图中<-表示公路,<-上的数字为距离,并且公路为单向公路,如1城市与5城市之间关系为:从1可以到5,距离为10km,但不能从5到1,其他类似。
    现在有个人住在1城市,他想去拜访住在5城市的朋友,求他所走的最短距离(不需要求路径)。

    对于这个问题我们就可以使用深度优先探索的方法,深度优先探索的意思是我们在这一步可以干什么,有几个选择,选择其中一个可能后,再到下一步可以干什么,有几个选择,直到达到目的,但这只是其中的一条路,我们需要找出其他的可能性,这就需要返回。深度优先探索就是一步一步都试图走完所有的点,尝试所有的可能性。如:我们是从1开始,1城市可以到2城市和5城市,我们选择5城市,达到目的并算出距离返回,在尝试走2城市,并且标记2城市已走过,防止陷入死循坏,就这样一步一步的尝试完所有的可能性,在每次达到目的后把这个方法所需的距离与保存的最小距离比较,最后输出最小距离。
    从题目中我们我们可以得到一个关系表:
    2个城市之间没有公路连接表示为-1,有则表示位之间的距离,每个城市到自己的距离为0;
        |
     1|        -1   -1   10 
    -1         -1   7
    3 |    -1          -1
    -1   -1    -1       5
    5|  -1   -1       -1    0
我们可以定义一个二维数组来保存这个表格:
int a[5][5] = {
0,  2, -1,-1,  10 },
{ -1,  0,  3,-1,  },
4, -1,  0, 4,  -1 },
{ -1, -1, -1,  0,  },
{ -1, -1,  3, -1,  }
};
我们还需要定义一个标记数组来标记这个城市是否已走过:
int sign[5] = { 0 };
定义一个全局变量来保存最小距离:
int min  = 999999;
核心代码为一个递归函数,全部代码如下:
#include

int a[5][5] = {
0,  2, -1,-1,  10 },
{ -1,  0,  3,-1,  },
4, -1,  0, 4,  -1 },
{ -1, -1, -1,  0,  },
{ -1, -1,  3, -1,  }
};
int sign[5] = { 0 };


int min = 999999;

void find_( int x, int count )
{
   //判断是否已经到达5城市
 if( x == 4 )
 {
  if( count < min )
  {
   min =count;//更新min值
   return;
  }
 }
 int i = 0;
 //寻找所有的可能性,并且尝试所有的可能性并移动到可以移动的城市
 for( i = 0; i < 5; i++ )
 {
  //这个城市与上个城市之间连通且之前并没有走过,就移动到这个城市
  if( a[x][i] > 0 &&sign[i] == 0 )
  {
   sign[i] =1;//标记这个城市已走过
   count +=a[x][i];
   find_( i,count );//移动到下个城市,寻找目标
   sign[i] =0;//返回后取消标记,防止其他路径出现错误
   count -=a[x][i];//这一步很重要,要将count的值还原
  }
 }
}

int main()
{
 sign[0] = 1;
 find_( 0, 0 );
 printf("min = %d", min );
 getchar();
 getchar();
 return 0;
}
运行结果为:C语言算法:深度优先探索

除了用深度优先探索这个方法,我们还可以用广度优先探索,在这里我先大家推荐一本书《啊哈!算法》,这是一本很棒的书,推荐大家去看。




















 

                                     
0 0