采用邻接表存储有向图,设计算法判断任意两个顶点间是否存在路径。设计算法,将一个无向图的邻接矩阵转换为邻接表。
采用邻接表存储有向图,设计算法判断任意两个顶点间是否存在路径。
设计步骤:
1.建立图
2.利用深度优先遍历,寻找两个结点
代码:
#define max 100 //顶点的最大个数
typedef struct st1//定义邻接表中结点类型
{
int adjvex; // 邻接点的位置
struct st1 *nextarc; //指向下一个结点
char info; //边的信息
} Arcnode;//定义邻接表中头结点类型
typedef struct
{//顶点信息
char vexdata;//指向第一个邻接结点
Arcnode *firstarc;
} AdjList;
typedef struct
{//定义邻接表表头
AdjList vextices[max];//存放表头结点信息
int vexnum, arcnum; //有向图的顶点数和边数
} AIGraph;
int visited[max];//定义深度优先搜索遍历数组,0表示未被访问过,1表示已被访问过
int flag = 0;//定义全局标志变量,用来确定两点间是否为通路,1表示存在,0表示不存在建立邻接表
AIGraph *create_AdjListGraph()
{
int n, e, i, j, k;
Arcnode *p;
AIGraph *al;
al = (AIGraph *)malloc(sizeof(AIGraph));
printf("请输入结点数:");
scanf("%d", &n);//初始化表头结点数组
for (i = 1; i <= n; i++)
{
al->vextices[i].vexdata = (char)i; //数据域存放顶点序号
al->vextices[i].firstarc = NULL;
}
printf("请输入边数:");
scanf("%d", &e);
printf("请输入弧的信息:");
for (i = 0; i < e; i++)
{
scanf("%d %d", &j, &k); // 依次读入弧的信息,结点k为结点j的邻接点
p = (Arcnode *)malloc(sizeof(Arcnode)); //申请结点空间,分配结点
p->adjvex=k;
p->info = ' ';
p->nextarc = al->vextices[j].firstarc;
al->vextices[j].firstarc = p;
}
al->vexnum = n;
al->arcnum = e;
return al;
}
void print(AIGraph *alg) //输出邻接表
{
int i;
Arcnode *p;
printf("图的邻接表为:\n");
for (i = 1; i <= alg->vexnum; i++)
{
printf("\t%d-", alg->vextices[i].vexdata);
p = alg->vextices[i].firstarc;
while (p != NULL)
{
printf("%d-", p->adjvex);
p = p->nextarc;
}
printf("<\n");
}
}//符号“<”表示空结点释放邻接表结点空间
void FreeAlGraph(AIGraph *alg)
{
int i;
Arcnode *p, *q;
for (i = 0; i <= alg->vexnum; i++)
{
p = alg->vextices[i].firstarc;
while (p != NULL)
{
q = p->nextarc;
free(p);
p = q;
}
}
}
int dfs(AIGraph *alg, int i, int n) //深度优先搜索遍历算法
{
Arcnode *p;
visited[i] = 1; //标志已被访问
p = alg->vextices[i].firstarc;
while (p != NULL)
{
if (visited[p->adjvex] == 0)
{
if (p->adjvex == n)
{
flag = 1;
}
dfs(alg, p->adjvex, n); //访问未被访问过的结点
if (flag == 1)
return 1;
}
p = p->nextarc;
} //搜索下一个邻接点
return 0;
}
void dfs_trave(AIGraph *alg, int m, int n)
{
int i;
for (i = 0; i <= alg->vexnum; i++)
visited[i] = 0;// 初始化访问数组
dfs(alg, m, n);
}
int main()
{
int m, n;//需要判断有无通路的两个结点
AIGraph *alg;
alg = create_AdjListGraph();
print(alg); //输出链接表
do
{
printf("请输入任意两个顶点(输入两个-1退出):");
scanf("%d %d", &m, &n);
dfs_trave(alg, m, n);
printf("\n");
if (flag == 1)
printf("顶点%d到%d存在通路\n", m, n);
else
printf("顶点%d到%d不存在通路\n", m, n);
flag = 0;
printf("ln");
} while (m != -1 && n != -1);
FreeAlGraph(alg);//释放结点空间
return 0;
}
设计算法,将一个无向图的邻接矩阵转换为邻接表。
设计步骤:
1.分别定义邻接矩阵和邻接图
2.查看邻接矩阵中的数据,如果为一则放入邻接图中
3.数据类型:
#define MAXV 100
//以下定义邻接矩阵类型
typedef struct
{
int vexs[MAXV];
int arcs[MAXV][MAXV];
int vexnum, arcnum;
} MGraph;
//以下定义邻接表类型
typedef struct ANode
{
int adjvex;
struct ANode *nextarc;
} ArcNode;
typedef struct Vnode
{
int data;
ArcNode *firstarc;
} VNode;
typedef struct
{
VNode vertices[MAXV];
int vexnum, arcnum;
} ALGraph;
代码:
void MatToList(MGraph g, ALGraph *G)
//将邻接矩阵g转换成邻接表G
{
int i, j;
ArcNode *p, *s;
for (i = 0; i < g.vexnum; i++)
G->vertices[i].firstarc = NULL;
for (i = 0; i < g.vexnum; i++)
for (j = 0; j < g.vexnum; j++)
if (g.arcs[i][j] != 0)
{
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = NULL;
if (!G->vertices[i].firstarc)
G->vertices[i].firstarc = p;
else
{
s = G->vertices[i].firstarc;
while (s->nextarc)
s = s->nextarc;
s->nextarc = p;
}
}
G->vexnum = g.vexnum;
G->arcnum = g.arcnum;
}
void Output(ALGraph *G)
//输出邻接表G
{
int i;
ArcNode *p;
for (i = 0; i < G->vexnum; i++)
{
p = G->vertices[i].firstarc;
printf("v%d:", i + 1);
while (p != NULL)
{
printf("%2d", p->adjvex);
p = p->nextarc;
}
printf("\n");
}
}
int main()
{
int i, j;
MGraph g; //定义图的邻接矩阵
ALGraph *G = (ALGraph *)malloc(sizeof(ALGraph)); //邻接表
int n, m;
printf("输入图G的邻接矩阵顶点数:\n");
scanf("%d", &n);
printf("输入图G的邻接矩阵边数:\n");
scanf("%d", &m);
int A[n][n]; //邻接矩阵
printf("输入图G的邻接矩阵:\n");
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &A[i][j]);
}
}
g.vexnum = n;
for (i = 0; i < g.vexnum; i++)
for (j = 0; j < g.vexnum; j++)
g.arcs[i][j] = A[i][j];
printf("图G的邻接矩阵转换成邻接表:\n");
MatToList(g, G);
Output(G);
return 0;
}