Bootstrap

数据结构第6章练习答案(PTA)

单选题

2-1具有5个顶点的有向完全图有多少条弧?(C

A.10        B.16        C.20        D.25

2-2关于图的邻接矩阵,下列哪个结论是正确的?(B

A.有向图的邻接矩阵总是不对称的

B.有向图的邻接矩阵可以是对称的,也可以是不对称的

C.无向图的邻接矩阵总是不对称的

D.无向图的邻接矩阵可以是不对称的,也可以是对称的

2-3在一个有向图中,所有顶点的入度与出度之和等于所有边之和的多少倍?(C

A.1/2        B.1        C.2        D.4

2-4下面给出的有向图中,有__个强连通分量。(C

 A.1 ({0,1,2,3,4})

B.1 ({1,2,3,4})

C.2 ({1,2,3,4}, {0})

D.5 ({0}, {1}, {2}, {3}, {4})

2-5给定一个有向图的邻接表如下图,则该图有__个强连通分量。(B

 

A.4 {{0, 1, 5}, {2}, {3}, {4}}

B.3 {{2}, {4}, {0, 1, 3, 5}}

C.1 {0, 1, 2, 3, 4, 5}

D.1 {0, 5, 1, 3}

2-6设无向图为 G=(V,E),其中 V={v1,v2,v3,v4},E={(v1,v2),(v3,v4),(v4,v1),(v2,v3),(v1,v3)}。则每个顶点的度依次为:(C

A.2, 1, 1, 1        B.1, 1, 2, 1        C.3, 2, 3, 2        D.2, 3, 2, 3

2-7在一个图中,所有顶点的度数之和等于图的边数的(C)倍。

A.1/2        B.1        C.2        D.4

2-8有关路径的定义是(A)。

A.由顶点和相邻顶点序偶构成的边所形成的序列

B.由不同顶点所形成的序列

C.由不同边所形成的序列

D.上述定义都不是

2-9若从无向图的任意一个顶点出发进行一次深度优先搜索可以访问图中所有的顶点,则该图一定是(B)图。

A.非连通        B.连通        C.强连通        D.有向

2-10下面(A)算法适合构造一个稠密图G的最小生成树。

A.Prim算法        B.Kruskal算法        C.Floyd算法        D.Dijkstra算法

2-11已知图的邻接矩阵如图所示,则从顶点v0出发按深度优先遍历的结果是(C)。

A.0 2 4 3 1 5 6         B.0 1 3 6 5 4 2        C.0 1 3 4 2 5 6        D.0 3 6 1 5 4 2

2-12在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的(B)倍。

A.1/2        B.1        C.2        D.4

2-13n个顶点的连通图用邻接矩阵表示时,该矩阵至少有(B)个非零元素。

A.n        B.2(n-1)        C.n/2        D.n*n

2-14在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是(D)。

A.G中有弧<Vi,Vj>

B.G中有一条从Vi到Vj的路径

C.G中没有弧<Vi,Vj>

D.G中有一条从Vj到Vi的路径

2-15关键路径是事件结点网络中(A)。

A.从源点到汇点的最长路径

B.从源点到汇点的最短路径

C.最长回路

D.最短回路

2-16具有N(N>0)个顶点的无向图至多有多少个连通分量?(D

A.0        B.1        C.N−1        D.N

2-17用邻接表表示图进行广度优先遍历时,通常借助(B)来实现算法。

A.栈        B.队列        C.树        D.图

2-18已知图的邻接表如图所示,则从顶点v0出发按广度优先遍历的结果是(D)。

A.0 1 3 2        B.0 2 3 1        C.0 3 2 1        D.0 1 2 3

2-19下面(B)方法可以判断出一个有向图是否有环。

A.深度优先遍历        B.拓扑排序        C.求最短路径        D.求关键路径

2-20使用迪杰斯特拉(Dijkstra)算法求下图中从顶点1到其他各顶点的最短路径,依次得到的各最短路径的目标顶点是:(B

 A.5, 2, 3, 4, 6        B.5, 2, 3, 6, 4        C.5, 2, 4, 3, 6        D.5, 2, 6, 3, 4

函数题

6-1 图的创建(邻接矩阵)

本题要求建立一个无向图,采用邻接矩阵做为存储结构。
例如:

函数接口定义:

在这里描述函数接口。例如:

void CreatMGraph(MGraph &G);//创建图G
int locate(MGraph G,char v);//返回顶点v的下标

G 为图,采用邻接矩阵存储结构,v 是顶点的值。

裁判测试程序样例:

#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 locate(MGraph G,char v);//返回顶点v的下标

int main()
{
    MGraph G;
    CreatMGraph(G);//创建图G
    printGraph(G);//打印该图
    return 0;
}

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");
    }
}

/* 请在这里填写答案 */

输入信息为:第一行给出图的顶点数n和边数e。第二行给出n个字符,表示n个顶点的数据元素的值。后面是e行,给出每一条边的两个顶点的值(顶点之间无空格)。

输出每个顶点的值以及各顶点的邻接点的值。

输入样例:

7 9
0123456
02
03
04
13
15
23
25
45
56

输出样例:

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

参考答案:

int locate(MGraph G,char v)
{ 						
   for(int i=0;i<G.vexnum;i++) if(G.vexs[i]==v) return i;
   return -1;
}
void CreatMGraph(MGraph &G)
{
	int i,j,k;
    char v1,v2;
	scanf("%d %d",&G.vexnum,&G.arcnum);
    getchar();
	for(i=0;i<G.vexnum;i++) scanf("%c",&G.vexs[i]);
    getchar();
	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("%c%c",&v1,&v2);
        getchar();
        i=locate(G,v1);
        j=locate(G,v2);
        G.arcs[i][j]=1;
        G.arcs[j][i]=G.arcs[i][j];
    }
    return;
}

 6-2 图的创建-邻接表

本题要求建立一个无向图,采用邻接表做为存储结构。
例如:

函数接口定义:

在这里描述函数接口。例如:

int locate(ALGraph G,char v);//求顶点v的下标
void CreatMGraph(ALGraph &G);//创建图G

G 是图,采用邻接表存储结构, v 为顶点的值。

裁判测试程序样例:

在这里给出函数被调用进行测试的例子。例如:
#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 printGraph(ALGraph G)
{
    int i;
    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");
    }
}

/* 请在这里填写答案 */

输入信息为:第一行给出图的顶点数n和边数e。第二行给出n个字符,表示n个顶点的数据元素的值。后面是e行,给出每一条边的两个顶点的值(顶点之间无空格)。

输出每个顶点的值以及各顶点的邻接点的值。

输入样例:

7 9
0123456
02
03
04
13
15
23
25
45
56

输出样例:

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

参考答案:

int locate(ALGraph G,char v)
{
   for(int i=0;i<G.vexnum;i++) if(G.vertices[i].data==v) return i;
   return -1;
}
void CreatMGraph(ALGraph &G)
{
    ArcNode *p1,*p2;
	scanf("%d %d",&G.vexnum,&G.arcnum);//输入总顶点数,总边数
    getchar();
    for(int i=0;i<G.vexnum;++i)//输入各点,构造表头结点表
    {
        scanf("%c",&G.vertices[i].data);//输入顶点值
        G.vertices[i].firstarc=NULL;//初始化表头结点的指针域为NULL
    }
    getchar();
    char v1,v2;
    for(int k=0;k<G.arcnum;++k)//输入各边,构造邻接表
    {
        scanf("%c%c",&v1,&v2);//输入一条边依附的两个顶点
        getchar();
        int i=locate(G,v1); 
        int j=locate(G,v2);
        p1=(ArcNode*)malloc(sizeof(ArcNode));
        p1->adjvex=j;//邻接点序号为j
        p1->nextarc=G.vertices[i].firstarc;
        G.vertices[i].firstarc=p1;//将新结点*p1插入顶点vi的边表头部
        p2=(ArcNode*)malloc(sizeof(ArcNode));
        p2->adjvex=i;//邻接点序号为i
        p2->nextarc= G.vertices[j].firstarc;
        G.vertices[j].firstarc=p2;//将新结点*p2插入顶点vj的边表头部
    }
    return;
}

 6-3 小岛计数

伽马群岛由若干小岛构成,开发者在某些小岛间修建了水上通路,使得群岛大部分连通,但也不排除部分小岛仍为孤岛,创建伽马群岛的地图,例如:

编写函数数一数该群岛共有多少个小岛。

函数接口定义:

在这里描述函数接口。例如:

int DFS(AMGraph G, int v);//以v为起点遍历图G(v所在的连通分量)
int  DFSTraverse(AMGraph G);//遍历图G

G为图,采用邻接矩阵存储结构,v为起点

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
#define MVNum 100

int visited[MVNum];

typedef struct{
    char vexs[MVNum];        //顶点向量
    int arcs[MVNum][MVNum]; //邻接矩阵
    int vexnum,arcnum;      //顶点数,边数
}AMGraph;

int DFS(AMGraph G, int v);//以v为起点遍历图G(v所在的连通分量)
int  DFSTraverse(AMGraph G);//遍历图G

int LocateVex(AMGraph G,char u)   //查询顶点u的下标
 {
   int i,count;
   for(i=0;i<G.vexnum;++i)
 if(   u==G.vexs[i]     )       return i;
   return -1;
 }

void CreateUDG(AMGraph &G){
    int i=0,j,count;
    char v1,v2;
     v1=getchar();
    while(v1!='#')
       {
           G.vexs[i]=v1;
           i++;
           v1=getchar();
       }
    G.vexnum=i;
       for(i = 0; i<    G.vexnum;++i)     //初始化邻接矩阵,所有元素均为0
       for(j = 0; j<    G.vexnum;++j)
         G.arcs[i][j] = 0;
       scanf("\n%c %c",&v1,&v2);
      while(v1!='#'&& v2!='#')
      {
      i = LocateVex(G, v1);
      j = LocateVex(G, v2);
      G.arcs[i][j] = 1;
      G.arcs[j][i] = 1;
      scanf("\n%c %c",&v1,&v2);
      }
  }
int main(){
    AMGraph G;
    CreateUDG(G);
    printf("%d",DFSTraverse(G));
    return 0;
}

/* 请在这里填写答案 */

输入格式:

第1行依次输入若干顶点的值(顶点之间无间隔),以‘#’结束(顶点不包含#)
接下来若干行输入每条边的信息,格式为:v1空格v2,直到输入‘# #’结束。

输出一个整数,为小岛数量

输入样例:

ABCD#
A B
A C
# #

输出样例:

4

参考答案:

int DFS(AMGraph G, int v)
{
    int count=0;
	visited[v]=true;
	for(int w=0; w<G.vexnum; w++)
    {
        if(!visited[w]) count+=DFS(G,w);
        else return 1;
    }
    return count;
}
int DFSTraverse(AMGraph  G)
{
	int sum=0;
    for(int v=0; v<G.vexnum; ++v) visited[v]=0;	//访问标志数组初始化
	for(int v=0; v<G.vexnum; ++v) if(!visited[v]) sum+=DFS(G,v);
    return sum;
}

;