搜索图中任意两点间的所有路径

来源:互联网 发布:mac系统顿号怎么打 编辑:程序博客网 时间:2024/05/25 13:33

从我之前写过的单源最短路径程序中把路径搜索函数分离出来就得到了搜索非负权重无环无向单边图中两顶点间所有路径的程序。这个程序稍作修改就可以适用于有向图,对两顶点间有多条边相连的图暂时没想到解决办法,望高手给出解答,对之前写的单源最短路径程序也是如此。

搜索图中两顶点间的所有路径的代码如下(C语言):

#include <stdio.h>#include <malloc.h>#define N 5 //无环单边非负权重无向图顶点数struct Path     //路径节点结构体类型{int sign;   //节点代表的顶点的标号int next;   //当前顶点的下一可达顶点标号struct Path *pnext;struct Path *pbefore;};typedef struct Path Path1;void FindRoad(int start, int end, int p[][N], int q[][N], int z[][N]);   //路径搜索函数,寻找start和end间的所有路径int Enable(int i, int j, int p[][N], int z[][N], int node[]);     //检查j是否是i的下一可达顶点,是返回1否则返回0int Search(int k, int option, int p[][N], int z[][N], int node[]);   //在顶点k上搜索顶点option后的第一个可达顶点,搜索成功返回顶点标号,否则返回-1void main(){int i, j, m, n;  //m为起始顶点,n为终点int p[N][N]={0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0};   //初始化邻接矩阵pint q[N][N]={0, 3, 0, 7, 8, 3, 0, 4, 0, 9, 0, 4, 0, 9, 2, 7, 0, 9, 0, 9, 8, 9, 2, 9, 0};   //初始化权重矩阵q,q[i][j]为连接i和j的边的权重int z[N][N];  //标志连接i和j的边是否已被访问的矩阵,z[i][j]=0表示未访问,=1表示已访问printf("请输入要搜索的路径的起始顶点标号:\n");  scanf("%d", &m);           //输入起始顶点标号printf("请输入要搜索的路径的终点标号:\n");scanf("%d", &n);           //输入终点标号         for (i=0; i<N; i++)           /*建立z矩阵并初始化为0*/{for (j=0; j<N; j++)z[i][j]=0;}    FindRoad(m-1, n-1, p, q, z);   //搜索m和n之间的所有路径并输出}void FindRoad(int start, int end, int p[][N], int q[][N], int z[][N]){int i, k;   //i为当前顶点,k为下一可达顶点int interval;int RoadLength;  //路径长度int count;      //路径计数int node[N]={0};  //Node数组标记各顶点在搜索过程中是否已被访问,Node[i]=0表示i+1顶点未被访问,Node[i]=1表示i+1顶点已被访问,这里首先初始化Node数组Path1 *psnewbe, *psnewaf, *head, *current;head=(Path1 *) malloc(sizeof(Path1));psnewbe=head;psnewaf=head;             //初始化路径链表head->pnext=NULL;head->pbefore=NULL;count=0;      //计数变量初始化node[start]=1; //start标记为已访问i=start; k=-1;  //i初始化为起始顶点while (1){      if (Search(i, k, p, z, node)==-1)   //搜索从k起的下一个可达顶点失败  {  if (i==start)    //路径搜索完毕,退出  break;  else  {  if (k==-1)  {  z[psnewaf->sign][i]=z[i][psnewaf->sign]=0;  node[i]=0;  i=psnewaf->sign;     //回溯  k=psnewaf->next;  continue;  }  else  {  z[psnewbe->sign][i]=z[i][psnewbe->sign]=0;  node[i]=0;  RoadLength-=q[psnewbe->sign][i];  free (psnewaf);  psnewbe->pnext=NULL;  psnewaf=psnewbe;                  //回溯  psnewbe=psnewbe->pbefore;                  i=psnewaf->sign;  k=psnewaf->next;  continue;  }  }  }  else             //搜索出下一可达顶点  {  if (k==-1)  {  current=(Path1 *) malloc(sizeof(Path1));  current->sign=i;                              //建立表示当前顶点i的路径节点  current->next=interval=Search(i, k, p, z, node);  if (i==start)  RoadLength=0;  else                                           //更新路径长度                       {  RoadLength+=q[psnewaf->sign][i];  }  z[current->next][i]=z[i][current->next]=1;     //连接i和下一可达顶点的边标记为已访问  node[current->next]=1;                   //下一可达顶点标记为已访问                current->pnext=NULL;  psnewaf->pnext=current;  current->pbefore=psnewaf;               //当前节点插入路径链表  psnewbe=psnewaf;  psnewaf=current;  }  else  {  psnewaf->next=interval=Search(i, k, p, z, node);        //更新下一可达节点标号  z[psnewaf->next][i]=z[i][psnewaf->next]=1;            //连接i和下一可达顶点的边标记为已访问  node[psnewaf->next]=1;                                 //下一可达顶点标记为已访问  }  i=interval;     //更新i为下一可达顶点  k=-1;           //k重置   if (i==end)    //到达终点  {  current=(Path1 *) malloc(sizeof(Path1));  current->sign=i;                           //建立表示终点的路径节点即路径链表尾节点              RoadLength+=q[psnewaf->sign][i];           //更新路径长度              current->pnext=NULL;  psnewaf->pnext=current;                    //尾节点插入路径链表  current->pbefore=psnewaf;  count++;                                 //路径计数变量自增  printf("第%d条路径:\n", count);              current=head->pnext;    /*输出找到的路径*/  while (1)  {  if (current->pnext==NULL)  {  printf("V%d", current->sign+1);  break;  }  else  {  printf("V%d->", current->sign+1);  }  current=current->pnext;  }  printf(" 路径长度%d\n", RoadLength);    //输出找到的路径长度                           free (current);                    //删除尾节点  psnewaf->pnext=NULL;  RoadLength-=q[psnewaf->sign][i];  z[psnewaf->sign][i]=z[i][psnewaf->sign]=0;           //回溯  node[i]=0;  i=psnewaf->sign;  k=psnewaf->next;  }  continue;  }}printf("共有%d条从V%d到V%d的路径\n", count, start+1, end+1);  //输出找到的路径总数if (head->pnext!=NULL)free(psnewaf);                    //完全删除路径链表free(head);}int Enable(int i, int j, int p[][N], int z[][N], int node[]){if (p[i][j]==0)  return 0;else{if (node[j]==1)return 0;else{    if (z[i][j]==1)   return 0;    else   return 1;}}}int Search(int k, int option, int p[][N], int z[][N], int node[]){int m=option;for (m++; m<N; m++){if (Enable(k, m, p, z, node)==1)return m;}return -1;}

对于如下的图:


其邻接矩阵和权重矩阵已在程序中数组的初始化列表中给出,程序运行时起始顶点输入为V1,终点输入为V3,则程序运行结果如下:



原创粉丝点击