数据机构_练习 第6章 图

1.选择题

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

  A1/2            B1             C2             D4 

答案:C

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

  A1/2            B1             C2             D4 

答案:B

解释:有向图所有顶点入度之和等于所有顶点出度之和。

3)具有n个顶点的有向图最多有(   )条边。  

An              Bn(n-1)         Cn(n+1)        Dn2 

答案:B

解释:有向图的边有方向之分,即为从n个顶点中选取2个顶点有序排列,结果为n(n-1)

4n个顶点的连通图用邻接距阵表示时,该距阵至少有   个非零元素。

An              B2(n-1)         Cn/2           Dn2 

答案:B

5G是一个非连通无向图,共有28条边,则该图至少有   个顶点。

A7              B8             C9             D10 

答案:C

解释:8个顶点的无向图最多有8*7/2=28条边,再添加一个点即构成非连通无向图,故至少有9个顶点。

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

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

答案:B

解释:即从该无向图任意一个顶点出发有到各个顶点的路径,所以该无向图是连通图。

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

A Prim算法      BKruskal算法   CFloyd算法     DDijkstra算法

答案:A

解释:Prim算法适合构造一个稠密图G的最小生成树,Kruskal算法适合构造一个稀疏图G的最小生成树。

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

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

答案:B

解释:广度优先遍历通常借助队列来实现算法,深度优先遍历通常借助栈来实现算法。

9)用邻接表表示图进行深度优先遍历时,通常借助(   )来实现算法。

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

答案:A

解释:广度优先遍历通常借助队列来实现算法,深度优先遍历通常借助栈来实现算法。

10)深度优先遍历类似于二叉树的(   )。

A.先序遍历      B.中序遍历        C.后序遍历      D.层次遍历

答案:A

11)广度优先遍历类似于二叉树的(   )。

A.先序遍历      B.中序遍历        C.后序遍历       D.层次遍历

答案:D

12图的BFS生成树的树高比DFS生成树的树高   )。

A.小            B相等            C小或相等       D大或相等

答案:C

解释:对于一些特殊的图,比如只有一个顶点的图,其BFS生成树的树高和DFS生成树的树高相等。一般的图,根据图的BFS生成树和DFS树的算法思想,BFS生成树的树高比DFS生成树的树高小。

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

                            图6.30  邻接矩阵

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

 

图6.31  邻接表

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

答案:DD

15下面   方法可以判断出一个有向图是否有环。

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

答案:B

2.应用

1)已知图6.32所示的有向图,请给出:

 每个顶点的入度和出度;    

 邻接矩阵;

 邻接表;

 逆邻接表。             

            

                    图6.32  有向图                          图6.33  无向网

答案:

 

2)已知如图6.33所示的无向网,请给出:

 邻接矩阵;    

 邻接表;

 最小生成树

答案:

 

 

            

 

                                    

 

a

b

4

c

3

 

 

 

 

 

 

 

 

 

 

 

 

b

a

4

c

5

d

5

e

9

 

 

 

 

 

 

c

a

3

b

5

d

5

h

5

 

 

 

 

 

 

d

b

5

c

5

e

7

f

6

g

5

h

4

e

b

9

d

7

f

3

 

 

 

 

 

 

 

 

 

f

d

6

e

3

g

2

 

 

 

 

 

 

 

 

 

g

d

5

f

2

h

6

 

 

 

 

 

 

 

 

 

 

3已知图的邻接矩阵如图6.34所示。试分别画出自顶点1出发进行遍历所得的深度优先生成树和广度优先生成树

 

 

 

 

 

 

4有向网如图6.35所示,试用迪杰斯特拉算法求出从顶点a到其他各顶点间的最短路径,完成表6.9

             

                       图6.34  邻接矩阵                               图6.35  有向网

6.9

D

终点

i=1

i=2

i=3

i=4

i=5

i=6

b

15

(a,b)

15

(a,b)

15

(a,b)

15

(a,b)

15

(a,b)

15

(a,b)

c

2

(a,c)

 

 

 

 

 

d

12

(a,d)

12

(a,d)

11

(a,c,f,d)

11

(a,c,f,d)

 

 

e

 

10

(a,c,e)

10

(a,c,e)

 

 

 

f

 

6

(a,c,f)

 

 

 

 

g

 

 

16

(a,c,f,g)

16

(a,c,f,g)

14

(a,c,f,d,g)

 

S

终点集

{a,c}

{a,c,f}

{a,c,f,e}

{a,c,f,e,d}

{a,c,f,e,d,g}

{a,c,f,e,d,g,b}

    

5试对图6.36所示的AOE-网:

 这个工程最早可能在什么时间结束    

 求每个活动的最早开始时间和最迟开始时间

 确定哪些活动是关键活动

 

 

 

答案:按拓扑有序的顺序计算各个顶点的最早可能开始时间Ve和最迟允许开始时间Vl。然后再计算各个活动的最早可能开始时间e和最迟允许开始时间l,根据l - e = 0? 来确定关键活动,从而确定关键路径。

 

 

1  

2 ¸

3 ·

 4 ¹

5 º

6 »

Ve

0

19

15

29

38

43

Vl

0

19

15

37

38

43

 

 

<1, 2>

<1, 3>

<3, 2>

<2, 4>

<2, 5>

<3, 5>

<4, 6>

<5, 6>

e

0

0

15

19

19

15

29

38

l

17

0

15

27

19

27

37

38

-e

17

0

0

8

0

12

8

0

此工程最早完成时间为43。关键路径为<1, 3><3, 2><2, 5><5, 6>

      

3.算法设计

1)分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操作:

 增加一个新顶点vInsertVex(G, v)

 删除顶点v及其相关的边,DeleteVex(G, v);

 增加一条边<vw>InsertArc(G, v, w);

 删除一条边<vw>DeleteArc(G, v, w)

[算法描述]

假设G为有向无权图,以邻接矩阵作为存储结构四个算法分别如下:

 增加一个新顶点v

Status Insert_Vex(MGraph &G, char v)//在邻接矩阵表示的图G上插入顶点v

{

if(G.vexnum+1)>MAX_VERTEX_NUM return INFEASIBLE;

G.vexs[++G.vexnum]=v;

return OK;

}//Insert_Vex

 

 删除顶点v及其相关的边,

Status Delete_Vex(MGraph &G,char v)//在邻接矩阵表示的图G上删除顶点v

{

n=G.vexnum;

if((m=LocateVex(G,v))<0) return ERROR;

G.vexs[m]<->G.vexs[n]; //将待删除顶点交换到最后一个顶点

for(i=0;i<n;i++)

{

G.arcs[m]=G.arcs[n];

G.arcs[m]=G.arcs[n]; //将边的关系随之交换

}

G.arcs[m][m].adj=0;

G.vexnum--;

return OK;

}//Delete_Vex

分析:如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加

 

 增加一条边<vw>

Status Insert_Arc(MGraph &G,char v,char w)//在邻接矩阵表示的图G上插入边(v,w)

{

if((i=LocateVex(G,v))<0) return ERROR;

if((j=LocateVex(G,w))<0) return ERROR;

if(i==j) return ERROR;

if(!G.arcs[j].adj)

{

G.arcs[j].adj=1;

G.arcnum++;

}

return OK;

}//Insert_Arc

 

 删除一条边<vw>

Status Delete_Arc(MGraph &G,char v,char w)//在邻接矩阵表示的图G上删除边(v,w)

{

if((i=LocateVex(G,v))<0) return ERROR;

if((j=LocateVex(G,w))<0) return ERROR;

if(G.arcs[j].adj)

{

G.arcs[j].adj=0;

G.arcnum--;

}

return OK;

}//Delete_Arc

 

以邻接表作为存储结构,本题只给出Insert_Arc算法.其余算法类似。

Status Insert_Arc(ALGraph &G,char v,char w)//在邻接表表示的图G上插入边(v,w)

{

if((i=LocateVex(G,v))<0) return ERROR;

if((j=LocateVex(G,w))<0) return ERROR;

p=new ArcNode;

p->adjvex=j;p->nextarc=NULL;

if(!G.vertices.firstarc) G.vertices.firstarc=p;

else

{

for(q=G.vertices.firstarc;q->q->nextarc;q=q->nextarc)

if(q->adjvex==j) return ERROR; //边已经存在

q->nextarc=p;

}

G.arcnum++;

return OK;

}//Insert_Arc

 

2一个连通图采用邻接表作为存储结构,设计一个算法,实现从顶点v出发的深度优先遍历的非递归过程。

[算法描述]

Void DFSn(Graph G,int v)

{  //从第v个顶点出发非递归实现深度优先遍历图G

Stack s;

SetEmpty(s);

Push(s,v);

While(!StackEmpty(s))

{ //栈空时第v个顶点所在的连通分量已遍历完

Pop(s,k);

If(!visited[k])

{ visited[k]=TRUE;

VisitFunc(k);          //访问第k个顶点

//将第k个顶点的所有邻接点进栈

for(w=FirstAdjVex(G,k);w;w=NextAdjVex(G,k,w))

{

if(!visited[w]&&w!=GetTop(s)) Push(s,w);    //图中有环时w==GetTop(s)

}

}

}

3设计一个算法,求图G中距离顶点v的最短路径长度最大的一个顶点,设v可达其余各个顶点。

[题目分析]

利用Dijkstra算法求v0到其它所有顶点的最短路径,分别保存在数组D[i]中,然后求出D[i]中值最大的数组下标m即可。

[算法描述]

int ShortestPath_MAX(AMGraph G, int v0){

    //Dijkstra算法求距离顶点v0的最短路径长度最大的一个顶点m

    n=G.vexnum;                     //nG中顶点的个数

    for(v = 0; v<n; ++v){              //n个顶点依次初始化 

       S[v] = false;                   //S初始为空集

       D[v] = G.arcs[v0][v];            //v0到各个终点的最短路径长度初始化

       if(D[v]< MaxInt)  Path [v]=v0;  //如果v0v之间有弧,则将v的前驱置为v0 

       else Path [v]=-1;               //如果v0v之间无弧,则将v的前驱置为-1 

      }//for 

      S[v0]=true;                     //v0加入S 

      D[v0]=0;                       //源点到源点的距离为0 

      /*开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S*/

      for(i=1;i<n; ++i){                //对其余n1个顶点,依次进行计算 

        min= MaxInt; 

        for(w=0;w<n; ++w) 

          if(!S[w]&&D[w]<min)  

              {v=w; min=D[w];}          //选择一条当前的最短路径,终点为v 

        S[v]=true;                    //v加入S 

        for(w=0;w<n; ++w)       //更新从v0VS上所有顶点的最短路径长度

        if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){ 

             D[w]=D[v]+G.arcs[v][w];    //更新D[w] 

             Path [w]=v;               //更改w的前驱为v 

        }//if 

    }//for

/*最短路径求解完毕,设距离顶点v0的最短路径长度最大的一个顶点为m */       

Max=D[0];

m=0;

for(i=1;i<n;i++)

if(Max<D[i]) m=i;

return m;

}

4试基于图的深度优先搜索策略写一算法,判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(ij)。

[题目分析]

引入一变量level来控制递归进行的层数

[算法描述]

int visited[MAXSIZE]; //指示顶点是否在当前路径上

int level1;//递归进行的层数

int exist_path_DFS(ALGraph G,int i,int j)//深度优先判断有向图G中顶点i到顶点j

是否有路径,是则返回1,否则返回0

{

  if(i==j) return 1; //i就是j

  else

  {

    visited[i]=1;

    for(p=G.vertices[i].firstarc;p;p=p->nextarclevel--)

    { level++;

      k=p->adjvex;

      if(!visited[k]&&exist_path(k,j)) return 1;//i下游的顶点到j有路径

}//for

  }//else

if (level==1)  return 0;

}//exist_path_DFS

5采用邻接表存储结构,编写一个算法,判别无向图中任意给定的两个顶点之间是否存在一条长度为为k的简单路径。

[算法描述]

int visited[MAXSIZE];

int exist_path_len(ALGraph G,int i,int j,int k)

//判断邻接表方式存储的有向图G的顶点ij是否存在长度为k的简单路径

{if(i==j&&k==0) return 1; //找到了一条路径,且长度符合要求

 else if(k>0)

  {visited[i]=1;

   for(p=G.vertices[i].firstarc;p;p=p->nextarc)

    {l=p->adjvex;

     if(!visited[l])

        if(exist_path_len(G,l,j,k-1)) return 1; //剩余路径长度减一

    }//for

   visited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中

  }//else

 return 0; //没找到

}//exist_path_len

 

 

 

  • 86
    点赞
  • 460
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
...... ( B )3. 有8个结点的无向图最多有 条边。 A.14 B. 28 C. 56 D. 112 ( C )4. 有8个结点的无向连通最少有 条边。 A.5 B. 6 C. 7 D. 8 ( C )5. 有8个结点的有向完全有 条边。 A.14 B. 28 C. 56 D. 112 ( B )6. 用邻接表表示进行广度优先遍历时,通常是采用 来实现算法的。 A.栈 B. 队列 C. 树 D. ...... 二、填空题(每空1分,共20分) 1. 有 邻接矩阵 、 邻接表 等存储结构,遍历有 深度优先遍历 、 广度优先遍历 等方法。 2. 有向G用邻接表矩阵存储,其第i行的所有元素之和等于顶点i的 出度 。 3. 如果n个顶点一个环,则它有 n 棵生成树。 4. n个顶点e条边的,若采用邻接矩阵存储,则空间复杂度为 O(n2) 。 5. n个顶点e条边的,若采用邻接表存储,则空间复杂度为 O(n+e) 。 ....... 1. 【严题集7.1①】已知如所示的有向,请给出该的: 每个顶点的入/出度; 邻接矩阵; 邻接表; 逆邻接表。 2. 【严题集7.7②】请对下的无向带权: 写出它的邻接矩阵,并按普里姆算法求其最小生成树; 写出它的邻接表,并按克鲁斯卡尔算法求其最小生成树。 ........ 五、算法设计题(每题10分,共30分) 1. 【严题集7.14③】编写算法,由依次输入的顶点数目、弧的数目、各顶点的信息和各条弧的信息建立有向的邻接表。 解:Status Build_AdjList(ALGraph &G) //输入有向顶点数,边数,顶点信息和边的信息建立邻接表 { InitALGraph(G); scanf("%d",&v); if(v<0) return ERROR; //顶点数不能为负 G.vexnum=v; scanf("%d",&a); if(a<0) return ERROR; //边数不能为负 G.arcnum=a; for(m=0;m<v;m++) G.vertices[m].data=getchar(); //输入各顶点的符号 for(m=1;m<=a;m++) { t=getchar();h=getchar(); //t为弧尾,h为弧头 if((i=LocateVex(G,t))<0) return ERROR; if((j=LocateVex(G,h))nextarc;q=q->nextarc); q->nextarc=p; } p->adjvex=j;p->nextarc=NULL; }//while return OK; }//Build_AdjList 2. 【严题集7.15③】试在邻接矩阵存储结构上实现的基本操作:DeleteArc(G,v,w)。 (刘提示:删除所有从第i个顶点出发的边的方法是 将邻接矩阵的第i行全部置0 ) ........

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值