Java数据结构 图.docx
《Java数据结构 图.docx》由会员分享,可在线阅读,更多相关《Java数据结构 图.docx(30页珍藏版)》请在冰豆网上搜索。
![Java数据结构 图.docx](https://file1.bdocx.com/fileroot1/2023-2/24/85179828-38e3-4e21-8894-8c75ebf1b509/85179828-38e3-4e21-8894-8c75ebf1b5091.gif)
Java数据结构图
Java数据结构图习题及答案
一、判断题
1.求最小生成树的Prim算法在边较少、结点较多时效率较高。
(对)
2.图的最小生成树的形状可能不唯一。
(错)
3.用邻接矩阵法存储一个图时,在不考虑压缩存储的情况下,所占用的存储空间大小只与图中结点个数有关,而与图的边数无关。
(错)
4.邻接表法只用于有向图的存储,邻接矩阵对于有向图和无向图的存储都适用。
(错)有向图和无向图既可以用邻接矩阵表示又可以用邻接表表示。
5.任何有向网络(AOV-网络)拓扑排序的结果是唯一的。
(错)
6.有回路的图不能进行拓扑排序。
(对)含有向环的找不到拓扑排序。
7.存储无向图的邻接矩阵是对称的,故只存储邻接矩阵的下(或上)三角部分即可。
(对)
8.用邻接矩阵A表示图,判定任意两个结点Vi和Vj之间是否有长度为m的路径相连,则只要检查Am的第i行第j列的元素是否为0即可。
(错)
9.在AOE网中一定只有一条关键路径。
(对)
10.缩短关键路径上活动的工期一定能够缩短整个工程的工期。
()
11.连通分量是无向图中的极小连通子图。
()
12.强连通分量是有向图中的极大强连通子图。
()
二、选择题
1.N条边的无向图的邻接表的存储中,边表的个数有(B)。
A)NB)2NC)N/2D)N*N
2.N条边的无向图的邻接多重表的存储中,边表的个数有(D)。
A)NB)2NC)N/2D)N*N
3.最短路径的生成算法可用(C)。
A)普里姆算法B)克鲁斯卡尔算法C)迪杰斯特拉算法D)哈夫曼算法
4.有拓扑排序的图一定是(D)。
A)有环图B)无向图C)强连通图D)有向无环图
5.图的邻接表如下图所示:
vertexfirstedge
V0
13∧
V1
023∧
1
V2
V3
01∧
(选择题5图)
V0
V1
V2
V3
(1)从顶点V0出发进行深度优先搜索,经历的结点顺序为(B)。
A)V0,V3,V2,V1B)V0,V1,V2,V3C)V0,V2,V1,V3D)V0,V1,V3,V2
(2)从顶点V0出发进行广度优先搜索,经历的结点顺序为(D)。
A)V0,V3,V2,V1B)V0,V1,V2,V3C)V0,V2,V1,V3D)V0,V1,V3,V2
6.设有向图n个顶点和e条边,进行拓扑排序时,总的计算时间为(D)。
A)O(nlog2e)B)O(en)C)O(elog2n)D)O(n+e)
7.对于含有n个顶点e条边的无向连通图,利用Kruskal算法生成最小代价生成树其时间复杂度为(A)。
A)O(elog2e)B)O(en)C)O(elog2n)D)O(nlog2n)
8.关键路径是事件结点网络中()。
A)从源点到汇点的最长路径B)从源点到汇点的最短路径
C)最长的回路
D)最短的回路
9.N个顶点的强连通图至少有(
(1))条边,这样的有向图的形状是(
(2))。
(1)A)nB)n+1C)n-1D)n(n-1)
(2)A)无回路B)有回路C)环状D)树状
10.设G有n个顶点和e条边,进行深度优先搜索的时间复杂度至多为(
(1))。
当G是非孤立顶点的连通图时有2e≥n,故可推得深度优先搜索的时间复杂度为(
(2))。
(1)A)O(ne)B)O(n+e)C)O(elog2n)D)O(e)
(2)A)O(ne)B)O(n+e)C)O(elog2n)D)O(e)
三、填空题
1.设无向图G中顶点数为n,则图G最少有___0____条边,最多有___
n(n-1)/2____条边。
若G为有向图,有n个顶点,则图G最少有____0___条边;最多有__n(n-1)_____条边。
2.具有n个顶点的无向完全图,边的总数为____n(n-1)/2____条;而在n个顶点的有向完全图中,边的总数为____n(n-1)_____条。
3.图的邻接矩阵表示法是表示____顶点__之间相邻关系的矩阵。
4.一个图的生成树的顶点是图的___________顶点。
5.写出下图所示的所有拓扑序列_v0,v1,v5,v2,v3,v6,v4_。
V3
V0
V41
V2
v1
V5
V6
(填空题5图)
6.在如下图所示的网络计划图中关键路径是____________,全部计划完成的时间是_____________。
12
15
5
308
17
14
11
207.2
24
16
13
4.56.5
8
(填空题9图)
7.设G有n个顶点和e条边,进行广度优先搜索的时间复杂度至多为__
_O(n+e)____。
当G是非孤立顶点的连通图时有2e≥n,故可推得广度优先搜索的时间复杂度为___O(n*n)____。
8.一个连通图的生成树是一个_______连通子图,n个顶点的生成树有_______条边。
9.对于含有n个顶点e条边的无向连通图,利用prim算法生成最小代价生成树其时间复杂度为______O(n*n)___。
10.邻接表和十字链表适合于存储__稀疏____图,邻接多重表适合于存储_____以边为主的__图。
四、简答题
1.对于如图所示的有向图,试给出
(1)每个顶点的入度和出度;①④
(2)邻接矩阵;⑤
(3)邻接表;
(4)逆邻接表;⑥
(5)强连通分量。
②③
(1)(简答题1图)
顶点
1
2
3
4
5
6
入度
2
2
1
3
2
1
出度
1
2
3
0
3
2
(2)邻接矩阵为R
000100
101000
R=010111
000000
110100
010010
(3)邻接表
顶点表出边表
V1
V2
V3
V4
∧
V5
V6
4
∧
1
2
1
2
3
∧
6
∧
4
5
2
4
∧
5
∧
(4)逆邻接表
顶点表入边表
V1
V2
V3
V4
V5
V6
5
∧
5
6
∧
2
∧
1
3
5
∧
3
3
∧
6
∧
2.设无向图G如图所示試给出
(1)
V4
V1
该图的邻接矩阵;
(2)
V6
V3
该图的邻接表;
(3)
V0
该图的多重邻接表;
(4)
V5
V2
从A出发的“深度优先”遍历序列;
(5)从A出发的“广度优先”遍历序列。
(简答题2图)
(1)该图的邻接矩阵为R
0110000
1010000
1001000
R=0110110
0001001
0001001
0000110
(2)该图的邻接表
顶点表边表
V0
V1
V2
V3
V4
V5
V6
1
0
0
1
3
3
4
2
∧
3
∧
3
∧
2
6
6
∧
5
∧
4
5
∧
3.设有向图G如图所示
试画出图G的十字链表结构,并写出图G的两个拓扑序列。
A
V5
V2
V41
v1
835
C
B
V3
V6
2
(简答题3图)(简答题4图)
写出图G的两个拓扑序列
V1,v3,v2,v6,v5,v4
V1,v2,v3,v6,v5,v4
4.试利用弗洛伊德(R.W.Floyed)算法,求图所示有向图的各对顶点之间的最短路径,并写出在执行算法过程中,所得的最短路径长度矩阵序列和最短路径矩阵序列。
5.下表列出了某工序之间的优先关系和各工序所需时间,求:
工序代号
所需时间
前序工序
工序代号
所需时间
前序工序
A
B
C
D
E
F
G
15
10
50
8
15
40
300
无
无
A
B
C,D
B
E
H
I
J
K
L
M
15
120
60
15
30
20
G,I
E
I
F,I
H,J,K
L
(简答题5表)
(1)画出AOE网;
(2)列出各事件中的最早、最迟发生时间;
找出该AOE网中的关键路径,并回答完成该工程需要的最短时间。
五、算法设计题
1.试以邻接矩阵为存储结构实现图的基本操作:
InsertVex(G,v)、InsertArc(G,v,w)、DeleteVex(G,v)和DeleteArc(G,v,w)。
importjava.io.*;
//最大边数和顶点数
//“邻接矩阵”类
classGraph{
staticintMaxEdges=50;
staticintMaxVertices=10;
staticdoubleMaxValue=9999.9;//无穷大
//存放顶点的数组
privatecharVerticesList[]=newchar[MaxVertices];
//邻接矩阵(存放两个顶点权值)
privatedoubleEdge[][]=newdouble[MaxVertices][MaxVertices];
privateintCurrentEdges;//现有边数
privateintCurrentVertices;//现有顶点数
//构造函数:
建立空的邻接矩阵
publicGraph(){
for(inti=0;ifor(intj=0;jif(i==j)
Edge[i][j]=0;//对角线
else//非对角线上无穷大
Edge[i][j]=MaxValue;
CurrentEdges=0;//现有边数
CurrentVertices=0;//现有顶点数
}
//查找指定的顶点的序号
publicintFindVertex(charvertex){
//在顶点数组里面查找
for(inti=0;iif(VerticesList[i]==vertex)
returni;//返回下标
return-1;//没有找到
}
//图空否?
publicbooleanIsGraphEmpty(){
returnCurrentVertices==0;
}
//图满否?
publicbooleanIsGraphFull(){
returnCurrentVertices==MaxVertices||
CurrentEdges==MaxEdges;
}
//取得顶点数
publicintNumberOfVertices(){
returnCurrentVertices;
}
//取得边数
publicintNumberOfEdges(){
returnCurrentEdges;
}
//按序号取得顶点值
publiccharGetValue(inti){
returni>=0&&i<=CurrentVertices-1
?
VerticesList[i]:
'';
}
//取得一条边的权值
publicdoubleGetWeight(intv1,intv2){
if(v1<0||v1>CurrentVertices-1)
return-1.0;//用-1表示出错
if(v2<0||v2>CurrentVertices-1)
return-1.0;
returnEdge[v1][v2];
}
//取得第一个邻接点的序号
publicintGetFirstNeighbor(intv){
if(v<0||v>CurrentVertices-1)
return-1;//用-1表示出错
//邻接矩阵的行号和列号是两个邻接点的序号
for(intcol=0;colif(Edge[v][col]>0&&//自身
Edge[v][col]returncol;
return-1;//无邻接点
}
//插入一个顶点
publicintInsertVertex(charvertex){
if(IsGraphFull())return-1;//插入失败
//顶点表增加一个元素
VerticesList[CurrentVertices]=vertex;
//邻接矩阵增加一行一列
for(intj=0;j<=CurrentVertices;j++){
Edge[CurrentEdges][j]=MaxValue;
Edge[j][CurrentEdges]=MaxValue;
}
Edge[CurrentEdges][CurrentEdges]=0;
CurrentVertices++;
returnCurrentVertices;//插入位置
}
//插入一个边
publicbooleanInsertEdge(intv1,intv2,doubleweight){
if(v1<0||v1>CurrentVertices-1)
returnfalse;//出错
if(v2<0||v2>CurrentVertices-1)
returnfalse;
Edge[v1][v2]=weight;//网,有向边
returntrue;
}
//删除一个顶点
publicbooleanRemoveVertex(intv){
if(v<0||v>CurrentVertices-1)
returnfalse;//出错
//修改顶点表
for(inti=v+1;iVerticesList[i-1]=VerticesList[i];
//修改邻接矩阵
intk=0;//累计将要删去的边数
for(inti=0;iif(Edge[v][i]>0&&//自身
Edge[v][i]k++;//第v行
for(inti=0;iif(Edge[i][v]>0&&//自身
Edge[i][v]k++;//第v列
//覆盖第v行
intj;
for(inti=v+1;ifor(j=0;jEdge[i-1][j]=Edge[i][j];
//覆盖第v列
for(j=v+1;jfor(inti=0;iEdge[i][j-1]=Edge[i][j];
CurrentVertices--;//修改顶点数
CurrentEdges-=k;//修改边数
returntrue;
}
//删除一个边
publicbooleanRemoveEdge(intv1,intv2){
if(v1<0||v1>CurrentVertices-1)
returnfalse;//用-1表示出错
if(v2<0||v2>CurrentVertices-1)
returnfalse;
if(v1==v2)returnfalse;
Edge[v1][v2]=MaxValue;//网,无路径
returntrue;
}
//打印邻接矩阵
publicvoiddisplay(){
inti,j;
System.out.println("顶点表");
for(i=0;iSystem.out.print(VerticesList[i]+"");
System.out.println('\n'+"邻接矩阵");
for(i=0;ifor(j=0;jif(Edge[i][j]==MaxValue)
System.out.print('@'+"");
else
System.out.print(Edge[i][j]+"");
System.out.println();
}
}
//主函数
publicstaticvoidmain(String[]args){
GraphG=newGraph();//邻接矩阵
//准备有向图(网)数据
charc[]={'A','B','C','D','E','F'};//顶点
intv[][]={//弧
{0,1},{0,3},{1,2},{2,3},{4,5},
{1,3},{2,4},{3,5},{4,3},{2,5}
};
doublee[]={2.3,3.6,6.5,2.5,1.7,
0.8,7.2,9.1,5.2,1.3};//权
//插入顶点
for(inti=0;i<6;i++)
G.InsertVertex(c[i]);
//插入弧
for(inti=0;i<10;i++)
G.InsertEdge(v[i][0],v[i][1],e[i]);
//打印输出
G.display();
//删除一个顶点
G.RemoveVertex(3);
G.display();
//删除一条边
G.RemoveEdge(2,4);
G.display();
}//main方法结束
}//“邻接矩阵”类结束
2.试以邻接表为存储结构实现算法设计题1中所列图的基本操作。
3.试以十字链表为存储结构实现算法设计题1中所列图的基本操作。
4.试以邻接多重表为存储结构实现算法设计题1中所列图的基本操作。
5.试写一算法由图的邻接链表存储得到图的十字链表存储。
6.写一算法,由依次输入图的顶点数目、边的数目、各顶点的信息和各条边的信息建立无向图的邻接多重表。
7.试写一个算法,判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)。
假设分别基于下述策略:
(1)图的深度优先搜索;
(2)图的宽度优先搜索。
8.试修改Prim算法,使之能在邻接表存储结构上实现求图的最小生成森林,并分析其时间复杂度(森林的存储结构为孩子-兄弟链表)。
9.以邻接表作存储结构实现求从源点到其余各顶点的最短路径的Dijkstra算法。
//最短路径的Dijkstra算法
//“邻接矩阵”类
classGraphPath{
staticintMaxEdges=50;
staticintMaxVertices=10;
staticdoubleMaxValue=9999.9;//无穷大
//存放顶点的数组
privatecharVerticesList[]=newchar[MaxVertices];
//邻接矩阵(存放两个顶点权值)
privatedoubleEdge[][]=newdouble[MaxVertices][MaxVertices];
privateintCurrentEdges;//现有边数
privateintCurrentVertices;//现有顶点数
//存放最短路径上的最后一个经由点
publicintpath[]=newint[MaxVertices];
//存放最短路径的权值
publicdoubledist[]=newdouble[MaxVertices];
//构造函数:
建立空的邻接矩阵
publicGraphPath(){
for(inti=0;ifor(intj=0;jif(i==j)
Edge[i][j]=0;//对角线
else//非对角线上无穷大
Edge[i][j]=MaxValue;
CurrentEdges=0;//现有边数
CurrentVertices=0;//现有顶点数
}
//查找指定的顶点的序号
publicintFindVertex(charvertex){
//在顶点数组里面查找
for(inti=0;i