数据结构第6章课后习题答案(下)

简介: 数据结构第6章课后习题答案(下)

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

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

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

③ 确定哪些活动是关键活动

图6.36  AOE-网

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

¸

·

 4 ¹

º

»

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)分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操作:

① 增加一个新顶点v,InsertVex(G, v);

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

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

④ 删除一条边<v,w>,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

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

③ 增加一条边<v,w>

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

④ 删除一条边<v,w>

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){                    //对其余n−1个顶点,依次进行计算

       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)                       //更新从v0V−S上所有顶点的最短路径长度

       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的路径(i≠j)。

[题目分析]

引入一变量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

目录
相关文章
|
8天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
29天前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
24 7
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
41 2
|
5月前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
77 1
|
5月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
45 1
|
5月前
|
机器学习/深度学习
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
35 1
|
5月前
|
算法
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
35 0
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
35 0
|
5月前
|
算法 C语言
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
36 0
|
5月前
|
算法
数据结构和算法学习记录——习题-翻转链表(不带表头结点逆置算法、带表头结点的链表逆置算法)
数据结构和算法学习记录——习题-翻转链表(不带表头结点逆置算法、带表头结点的链表逆置算法)
33 0