图相关的练习和实验。 时间:2020-6-7
实验
程序填空
5-1 图的建立-邻接矩阵
本题要求建立一个无向图,采用邻接矩阵做为存储结构。
例如
输入信息为:第一行给出图的顶点数n和边数e。第二行给出n个字符,表示n个顶点的数据元素的值。后面是e行,给出每一条边的两个顶点编号。
输出每个顶点的值以及各顶点的邻接点的值。
输入样例为:
7 9
0123456
0 2
0 3
0 4
1 3
1 5
2 3
2 5
4 5
5 6
输出样例为
0: 2 3 4
1: 3 5
2: 0 3 5
3: 0 1 2
4: 0 5
5: 1 2 4 6
6: 5
#include <stdio.h>
#define MVNum 100 //最大顶点数
typedef struct{
char vexs[MVNum]; //存放顶点的一维数组
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和边数
}MGraph;
void CreatMGraph(MGraph *G);/* 创建图 */
void printGraph(MGraph G);/*输出图 */
int main()
{
MGraph G;
CreatMGraph(&G);
printGraph(G);
return 0;
}
void CreatMGraph(MGraph *G)
{
int i,j,k;
char a;
scanf("%d%d",&G->vexnum,&G->arcnum);
getchar();
for(i=0;i<G->vexnum;i++)
scanf("%c",&G->vexs[i]);
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=0;
for(k=0;k<G->arcnum;k++) {
scanf("%d%d",&i,&j);
G->arcs[i][j]=1;
G->arcs[j][i]=1;
}
}
void printGraph(MGraph G)
{
int i,j;
for(i=0;i<G.vexnum;i++)
{
printf("%c:",G.vexs[i]);
for(j=0;j<G.vexnum;j++)
if (G.arcs[i][j]) printf(" %c",G.vexs[j]);
printf("\n");
}
}
5-2 图的建立-邻接表
的值本题要求建立一个无向图,采用邻接表做为存储结构。
例如
输入信息为:第一行给出图的顶点数n和边数e。第二行给出n个字符,表示n个顶点的数据元素的值。后面是e行,给出每一条边的两个顶点编号。
输出每个顶点的值以及各顶点的邻接点的值。
输入样例为:
7 9
0123456
0 2
0 3
0 4
1 3
1 5
2 3
2 5
4 5
5 6
输出样例为
0: 4 3 2
1: 5 3
2: 5 3 0
3: 2 1 0
4: 5 0
5: 6 4 2 1
6: 5
#include <stdio.h>
#include <stdlib.h>
#define MVNum 100 //最大顶点数
typedef struct ArcNode{ //表结点
int adjvex; //邻接点的位置
struct ArcNode * nextarc; //指向下一个表结点的指针
}ArcNode;
typedef struct VNode{
char data; //顶点信息
ArcNode * firstarc; //指向第一个表结点的指针
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
typedef struct{
AdjList vertices; //头结点数组
int vexnum, arcnum; //图的当前顶点数和边数
}ALGraph;
void CreatMGraph(ALGraph *G);/* 创建图 */
void printGraph(ALGraph G);/*输出图 */
int main()
{
ALGraph G;
CreatMGraph(&G);
printGraph(G);
return 0;
}
void CreatMGraph(ALGraph *G)
{
int i,j,k;
ArcNode *s;
scanf("%d%d",&G->vexnum,&G->arcnum);
getchar();
for(i=0;i<G->vexnum;i++)
scanf("%c",&G->vertices[i].data);
for(i=0;i<G->vexnum;i++)
G->vertices[i].firstarc=NULL;
for(k=0;k<G->arcnum;k++) {
scanf("%d%d",&i,&j);
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=j;
s->nextarc=G->vertices[i].firstarc;
G->vertices[i].firstarc=s;
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=i;
s->nextarc=G->vertices[j].firstarc;
G->vertices[j].firstarc=s;
}
}
void printGraph(ALGraph G)
{
int i,j;
ArcNode *p;
for(i=0;i<G.vexnum;i++)
{
printf("%c:",G.vertices[i].data);
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
printf(" %c",G.vertices[p->adjvex].data);
printf("\n");
}
}
函数题
6-2 邻接矩阵存储图的深度优先遍历
试实现邻接矩阵存储图的深度优先遍历。
函数接口定义:
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
其中MGraph是邻接矩阵存储的图,定义如下:
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
函数DFS应从第V个顶点出发递归地深度优先遍历图Graph,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按序号递增的顺序。题目保证V是图中的合法顶点。
裁判测试程序样例:
#include <stdio.h>
typedef enum {false, true} bool;
#define MaxVertexNum 10 /* 最大顶点数设为10 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */
MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */
void Visit( Vertex V )
{
printf(" %d", V);
}
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
int main()
{
MGraph G;
Vertex V;
G = CreateGraph();
scanf("%d", &V);
printf("DFS from %d:", V);
DFS(G, V, Visit);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:给定图如下
输出样例:
DFS from 5: 5 1 3 0 2 4 6
代码:
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
int j=0;
Visit(V);
Visited[V]=true;
for(j=0;j<Graph->Nv;j++)
{
if((Graph->G[V][j]==1)&&(!Visited[j]))
DFS(Graph,j,Visit);
}
}
练习
判断题
1-1
无向图中的一条边,在其邻接表存储结构中对应两个弧结点。T
1-2
有n-1条边的图肯定都是生成树。F
1-3
任何无向图都存在生成树。F
1-4
一个无向图G,若某顶点v到其它每个顶点都有至少一条路径,则图G只有1个连通分量。T
1-5
无向连通图所有顶点的度之和为偶数。T
1-6
用邻接表法存储图,占用的存储空间数只与图中结点个数有关,而与边数无关。F
1-7
在一个有向图中,所有顶点的入度与出度之和等于所有边之和的2倍。T
1-8
在任一有向图中,所有顶点的入度之和等于所有顶点的出度之和。T
1-9
AOE图的关键路径就是最长的路径。T
1-10
拓扑排序的有向图中,最多存在一个环路。F
1-11
若有向图G存在拓扑排序序列,则G一定不是强连通的。T
选择题
2-1
具有5个顶点的有向完全图有多少条弧?C
A.10
B.16
C.20
D.25
2-2
若一个有向图用邻接矩阵表示,则第i个结点的入度就是:C
A.第i行的元素个数
B.第i行的非零元素个数
C.第i列的非零元素个数
D.第i列的零元素个数
2-3
关于图的邻接矩阵,下列哪个结论是正确的?B
A.有向图的邻接矩阵总是不对称的
B.有向图的邻接矩阵可以是对称的,也可以是不对称的
C.无向图的邻接矩阵总是不对称的
D.无向图的邻接矩阵可以是不对称的,也可以是对称的
2-4
在一个有向图中,所有顶点的入度与出度之和等于所有边之和的多少倍?C
A.1/2
B.1
C.2
D.4
2-18
n个顶点的连通图用邻接矩阵表示时,该矩阵至少有( B)个非零元素。
A.n
B.2(n-1)
C.n/2
D.n*n
2-19
在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是(D )。
A.G中有弧<Vi,Vj>
B.G中有一条从Vi到Vj的路径
C.G中没有弧<Vi,Vj>
D.G中有一条从Vj到Vi的路径
2-20
下列哪一种图的邻接矩阵是对称矩阵?(B )
A.有向图
B.无向图
C.AOV网
D.AOE网
2-21
关键路径是事件结点网络中(A )。
A.从源点到汇点的最长路径
B.从源点到汇点的最短路径
C.最长回路
D.最短回路
2-22
具有N(N>0)个顶点的无向图至多有多少个连通分量?D
A.0
B.1
C.N−1
D.N
2-23
用邻接表表示图进行广度优先遍历时,通常借助(B )来实现算法。
A.栈
B.队列
C.树
D.图