【数据结构】图的遍历与应用

图相关的练习和实验。 时间: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.图

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值