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

  这是我从一本书上看的的一道题,特来与大家分享,如下:
  假设有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  |  2  |  3  |  4  |  5  |
     1 |  0     2     -1    -1    10 
     2 |  -1    0     3     -1    7
     3 |  4     -1    0     4     -1
     4 |  -1    -1    -1    0     5
     5 |  -1    -1    3     -1     0
我们可以定义一个二维数组来保存这个表格:
int a[5][5] = {
{  0,  2, -1, -1,  10 },
{ -1,  0,  3, -1,  7  },
{  4, -1,  0,  4,  -1 },
{ -1, -1, -1,  0,  5  },
{ -1, -1,  3, -1,  0  }
};
我们还需要定义一个标记数组来标记这个城市是否已走过:
int sign[5] = { 0 };
定义一个全局变量来保存最小距离:
int min  = 999999;
核心代码为一个递归函数,全部代码如下:
#include

int a[5][5] = {
{  0,  2, -1, -1,  10 },
{ -1,  0,  3, -1,  7  },
{  4, -1,  0,  4,  -1 },
{ -1, -1, -1,  0,  5  },
{ -1, -1,  3, -1,  0  }
};
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语言算法:深度优先探索

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




















 

                                     

你可能感兴趣的:(C语言算法:深度优先探索)