[问题描述]
试基于图的深度优先搜索策略编写一程序,判别以邻接表方式存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i≠j)。
用邻接表存储一个有向图,深度优先遍历该图,判断顶点Vi到Vj顶点的路径是否存在。
[输入]
结点个数,邻接表信息,起始点,终点
[输出]
输出有向图,判断结果
[存储结构]
顺序存储结构和链式存储结构
[算法基本思想]
创建一个有向图:在初始化的基础上,为每个顶点按单链表形式添加边结点并初始化,如果输入非负数则分配空间并赋值给边结点,若输入负数则结束当前顶点的初始化,进入下一个顶点,直到最后一个顶点;输出有向图:按邻接表的结构依次输出,直到最后一个结点;深度遍历判断:递归算法,在邻接表的基础上,从起始点开始,访问每个邻接点,直到终点被访问或所有点均被访问,若终点被访问则判断路径存在,否则不存在。
源程序
#include<bits\stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define MAX_VERTEX_NUM 100//最大边数
#define VERTEX_NUM 6
#define ARC_NUM 10
#define MAXQSIZE 100
#define INF 99 //最大值∞,INT_MAX
typedef struct ArcNode{ // 弧节点
int adjvex;//该弧所指向的顶点的位置
ArcNode* nextarc;//下一条弧的指针
//InfoType*info;//该弧相关信息的指针
}ArcNode;
typedef struct VNode{//顶点结点
int data;
ArcNode* fistarc;//指向依附于该顶点的弧指针
}VNode,AdjList[MAX_VERTEX_NUM];//结点数组
typedef struct ALGragh{
//邻接表
AdjList vertices;
int vexnum,arcnum;//图当前的顶点数和弧数
int kind;//图的种类标志
bool visited[MAX_VERTEX_NUM];
}ALGragh;
ALGragh*G=(ALGragh*)malloc(sizeof(ALGragh));
int i,j,k;
bool hasPath=0;
void createLink(){//创建邻接表
printf("请输入顶点数n 弧数m:");
scanf("%d %d",&G->vexnum,&G->arcnum);
printf("创建的所有点:");
for(i=0;i<G->vexnum;i++){ G->vertices[i].fistarc = 0;printf("V%d ",i);}printf("\n");
for(j=0;j<G->arcnum;j++){
printf("第%d条弧起点编号、终点编号:",j+1);
scanf("%d %d",&i,&k);
ArcNode *p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = k; //将边所指向的点编号赋值
p->nextarc = G->vertices[i].fistarc;
G->vertices[i].fistarc = p;
}
}
void existPath(int d,int z){//两点是否连通
G->visited[d] = 1;
ArcNode *p = G->vertices[d].fistarc;
if(d == z)hasPath = 1;
while(p){
if(p->adjvex==z)hasPath = 1;
if(!G->visited[p->adjvex])existPath(p->adjvex,z);
p = p->nextarc;
}
}
void setFlase(){//visited置零
hasPath = 0;
for(i=0;i<G->vexnum;i++) G->visited[i] = 0;
}
int main(){
system("color f0");
createLink();
setFlase();
printf("请输入两点编号:");
scanf("%d %d",&i,&k);
existPath(i,k);
if(hasPath)
{
printf("两点连通!\n");
}
else printf("两点不连通!\n");
system("pause");
return 0;
}
该程序的功能完整地满足了题目地所有要求,输出格式也简洁明了,但在创建有向图、输有向图时结束条件没有采用链表形式(指针),而是用顺序形式。其时间复杂度为O(n2),空间上使用了两个辅助空间,较为耗费。
使用链式存储结构时,注意有无头结点、头指针是否为空;要熟练掌握指针的使用、图的存储结构和基本操作代码。