20202312郭威 实验九 《面向对象程序设计》实验报告

2002312 2021-2022-1 实验九 《图》实验报告

课程:《程序设计与数据结构》
班级: 2023
姓名: 郭威
学号:20202312
实验教师:王志强
实验日期:2021年12月9日
必修/选修: 必修

1.实验内容

(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)

PS:本题12分。目前没有明确指明图的顶点和连通边,如果雷同或抄袭,本次实验0分。
实验报告中要根据所编写的代码解释图的相关算法

2.实验过程及结果

(1)初始化

 

 

 1 public class Graph {
 2     Vertex[] VertexArray;
 3     Edge[] EdgeArray;
 4     int edgenum,vertexnum;
 5     int adjmatrix[][];
 6     public void CreateGraph(int num)
 7     {
 8         Scanner scan = new Scanner(System.in);
 9         System.out.println("请输入顶点数与边数");
10         vertexnum=scan.nextInt();
11         edgenum=scan.nextInt();
12         adjmatrix=new int[vertexnum][vertexnum];
13         VertexArray=new Vertex[vertexnum];
14         EdgeArray=new Edge[edgenum];
15         System.out.println("请输入顶点:");
16         for(int i=0;i<vertexnum;i++){
17             VertexArray[i]=new Vertex(scan.next());
18         }
19         for(int i=0;i<edgenum;i++){
20             String a,b;
21             Vertex from,to;
22             int c;
23             System.out.println("请输入边的两顶点与权值:");
24             from=SearchVertex(scan.next());
25             to=SearchVertex(scan.next());
26             c= scan.nextInt();
27             EdgeArray[i]=new Edge(from,to,c);
28             adjmatrix[SearchIndex(from.name)][SearchIndex(to.name)]=c;
29             from.outdegree++;
30             to.indegree++;
31             if(num==2){
32                 adjmatrix[SearchIndex(to.name)][SearchIndex(from.name)]=c;
33                 from.outdegree--;
34                 to.indegree--;
35             }
36         }
37     }
38 
39     public int SearchIndex(String name){
40         for(int i=0;i<VertexArray.length;i++)
41         {
42             if(VertexArray[i].name.equals(name))
43                 return i;
44         }
45         return -1;
46     }
47 
48     public Vertex SearchVertex(String name)
49     {
50         for(int i=0;i<VertexArray.length;i++){
51             if(VertexArray[i].name.equals(name))
52                 return VertexArray[i];
53         }
54         return null;
55     }

 

 

(2) 图的遍历:

 1 public String BreadthFirstTraversal(String first){
 2         Vertex temp;
 3         String result="";
 4         Queue<Vertex> queue=new LinkedList();
 5         queue.offer(SearchVertex(first));
 6         SearchVertex(first).Mark();
 7         while(!queue.isEmpty()){
 8             temp=queue.poll();
 9             result+=temp.name;
10             for(int i=0;i<vertexnum;i++){
11                 if(adjmatrix[SearchIndex(temp.name)][i]!=0&&!VertexArray[i].isMark) {
12                     queue.offer(VertexArray[i]);
13                     VertexArray[i].Mark();
14                 }
15             }
16         }
17         for(int i=0;i<vertexnum;i++){ VertexArray[i].wipe(); }
18         return result;
19     }
20     public String DepthTraversal(String first){
21         String result=first;
22         SearchVertex(first).Mark();
23         for(int i=0;i<vertexnum;i++){
24             if(adjmatrix[SearchIndex(first)][i]!=0&&!VertexArray[i].isMark) {
25                 result += DepthTraversal(VertexArray[i].name);
26             }
27         }
28         return result;
29     }
30     public String DepthFirstTraversal(String first){
31         String a=DepthTraversal(first);
32         for(int i=0;i<vertexnum;i++){ VertexArray[i].wipe(); }
33         return a;
34     }

 

 (3) 有向图的拓扑排序

 1 public String topology(){
 2         String a="";
 3         Stack<Vertex> stack=new Stack<Vertex>();
 4         int indegreearray[]=new int[vertexnum];
 5         boolean ismark[]=new boolean[vertexnum];
 6         for(int i=0;i< VertexArray.length;i++) {
 7             indegreearray[i] = VertexArray[i].indegree;
 8             ismark[i]=false;
 9             if(indegreearray[i]==0){stack.push(VertexArray[i]);ismark[i]=true;}
10         }
11         while(!stack.isEmpty()) {
12             Vertex temp = stack.pop();
13             a += temp.name + " ";
14             for (int i = 0; i < vertexnum; i++) {
15                 if (adjmatrix[SearchIndex(temp.name)][i]!=0) {
16                     indegreearray[i]--;
17                     for (int j = 0; j < vertexnum; j++) {
18                         if (indegreearray[j] == 0 && !ismark[j]) { stack.push(VertexArray[j]);ismark[j] = true; }
19                     }
20                 }
21             }
22         }
23         for(int i=0;i<vertexnum;i++)
24             if(!ismark[i])return "该图存在环";
25         return a;
26     }

 

(4) 完成无向图的最小生成树

 1 public Graph spanningTree(){
 2         Graph spanning =new Graph();
 3         Scanner scan=new Scanner(System.in);
 4         Edge []an=new Edge[vertexnum-1];
 5         int anweight[]=new int[vertexnum-1];
 6         String a="";
 7         spanning.VertexArray=this.VertexArray;
 8         spanning.EdgeArray=new Edge[vertexnum-1];
 9         spanning.edgenum=vertexnum-1;
10         spanning.vertexnum=vertexnum;
11         System.out.print("请输入起点:");
12         Vertex as= SearchVertex(scan.next());
13         boolean appear=false;
14         for(int i=0;i<vertexnum-1;i++){
15             an[i]=new Edge();
16             an[i].from=as;
17             if(VertexArray[i]==as)appear=true;
18             if(appear)an[i].to=VertexArray[i+1];
19             else an[i].to=VertexArray[i];
20             for(int j=0;j<edgenum;j++){
21                 if(EdgeArray[j].from==an[i].from&&EdgeArray[j].to==an[i].to) {an[i].weight=EdgeArray[j].weight;break;}
22                 if(EdgeArray[j].from==an[i].to&&EdgeArray[j].to==an[i].from){an[i].weight=EdgeArray[j].weight;break;}
23             }
24         }
25         for(int r=0,min=0,max=0;r<vertexnum-1;r++){
26             for(int j=0;j<vertexnum-1;j++){
27                 if(an[j].weight<an[min].weight&&an[j].weight>0&&anweight[j]>=0){min=j;}
28                 if(an[j].weight>an[max].weight&&an[j].weight>0&&anweight[j]>=0){max=j;}
29             }
30             anweight[min]=-1;
31             spanning.EdgeArray[r]=an[min];
32             a+=an[min].from.name+" "+an[min].to.name+" "+an[min].weight+"\n";
33             for(int t=0;t<vertexnum-1;t++){
34                 for(int j=0;j<edgenum;j++){
35                     if(EdgeArray[j].from==an[min].to&&EdgeArray[j].to==an[t].to&&anweight[t]>=0) {
36                         anweight[t]=EdgeArray[j].weight;
37                         break;}
38                     if(EdgeArray[j].from==an[t].to&&EdgeArray[j].to==an[min].to&&anweight[t]>=0){
39                         anweight[t]=EdgeArray[j].weight;
40                         break;}
41                 }
42                 if(anweight[t]<an[t].weight&&anweight[t]>0){an[t].from=an[min].to;an[t].weight=anweight[t];}
43                 if(an[t].weight==-1){an[t].from=an[min].to;an[t].weight=anweight[t];}
44             }
45             min=max;
46         }
47         System.out.println(a);
48         return spanning;
49     }

 

(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)

 1 public void Dijkstra(){
 2         Scanner scan=new Scanner(System.in);
 3         String a="",b="";
 4         System.out.print("请输入起点");
 5         b=scan.next();
 6         Vertex begin=SearchVertex(b);
 7         Path ShortestEdge[]=new Path[vertexnum];
 8         Path shortest[]=new Path[vertexnum-1];
 9         for(int i=0,j=0;i<vertexnum;i++){
10             if(VertexArray[i]!=begin) {
11                 ShortestEdge[j]=new Path(begin,VertexArray[i],1000000000);j++;
12             }
13         }
14         for(int i = 0,k=0; i<vertexnum-1;i++){
15             Path min=new Path();
16             Path con=new Path(3);
17             for(int j=0;j<vertexnum;j++){
18                 int tempweight=adjmatrix[SearchIndex(begin.name)][j];
19                 if(SearchIndex(begin.name)!=j) {
20                     if (ShortestEdge[k].weight!= con.weight) {
21                         Path temp1 =new Path(ShortestEdge[k]), temp2 ;
22                         if(i>0) temp2 =new Path(shortest[i-1]);
23                         else temp2=ShortestEdge[k];
24                         if (tempweight != 0 &&temp2.Add(begin, ShortestEdge[k].end, tempweight).weight < temp1.weight){
25                             ShortestEdge[k]=temp2;
26                         }
27                         else {
28                             ShortestEdge[k] = temp1;
29                         }
30                         if (ShortestEdge[k].weight < min.weight) min = ShortestEdge[k];
31                     }
32                     k++;
33                 }
34             }
35             ShortestEdge[vertexnum-1]=new Path(min);
36             shortest[i]=new Path(min);
37             a+=b+" "+shortest[i].end.name+" "+shortest[i].weight+"\n";
38             begin=min.end;
39             min.weight=con.weight;
40             k=0;
41         }
42         System.out.println(a);
43     }

  

3.实验过程中遇到的问题和解决过程

- 问题1:在输入无向图时老是报错,进行调试也没能解决
- 问题1解决方案:仔细查找,发现是自己的输入方式出现了问题,调整后,显示成功。

 ## 其他(感悟、思考等)

  感觉这次图的实验好难啊,好多算法自己还不是很清楚,感觉还得多花时间去搞懂。

## 参考资料

-  [《Java程序设计与数据结构教程(第二版)》](https://book.douban.com/subject/26851579/)

-  [《Java程序设计与数据结构教程(第二版)》学习指导](http://www.cnblogs.com/rocedu/p/5182332.html)
-  ...

 

posted @ 2021-12-19 16:52  20202312郭威  阅读(88)  评论(0编辑  收藏  举报