Prechádzať zdrojové kódy

finish graph funcitons.

171870002 5 rokov pred
rodič
commit
6a16623d94

+ 25 - 3
src/main/java/com/example/data_structure/controller/GraphController.java

@@ -1,11 +1,15 @@
 package com.example.data_structure.controller;
 package com.example.data_structure.controller;
 
 
+import com.example.data_structure.common.Response;
+import com.example.data_structure.domain.UDUWGraph;
+import com.example.data_structure.domain.UDWGraph;
 import com.example.data_structure.service.GraphService;
 import com.example.data_structure.service.GraphService;
+import com.example.data_structure.vo.GraphTraversalVO;
+import com.example.data_structure.vo.PrimMinimumSpanningTree;
+import javafx.scene.chart.ValueAxis;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 
 @RestController
 @RestController
 @CrossOrigin
 @CrossOrigin
@@ -13,4 +17,22 @@ public class GraphController {
 
 
     @Autowired
     @Autowired
     GraphService graphService;
     GraphService graphService;
+
+    @GetMapping(value = "/graph/get-breath-first-traversal")
+    public Response getGraphBreadthFirstTraversal(@RequestParam UDUWGraph graph, @RequestParam int startVertex){
+        GraphTraversalVO vo=graphService.getBreadthFirstTraversal(graph,startVertex);
+        return Response.buildSuccess(vo);
+    }
+
+    @GetMapping(value = "/graph/get-depth-first-traversal")
+    public Response getGraphDepthFirstTraversal(@RequestParam UDUWGraph graph,@RequestParam int startVertex){
+        GraphTraversalVO vo=graphService.getDepthFirstTraversal(graph,startVertex);
+        return Response.buildSuccess(vo);
+    }
+
+    @GetMapping(value = "/graph/get-prim-minimum-spanning-tree")
+    public Response getPrimMinimumSpanningTree(@RequestParam UDWGraph graph,@RequestParam int startVertex){
+        PrimMinimumSpanningTree vo=graphService.getPrimMinimumSpanningTree(graph,startVertex);
+        return Response.buildSuccess(vo);
+    }
 }
 }

+ 80 - 10
src/main/java/com/example/data_structure/service/GraphService.java

@@ -125,7 +125,7 @@ public class GraphService {
     //获取无向非带权图的深度优先遍历
     //获取无向非带权图的深度优先遍历
     public GraphTraversalVO getDepthFirstTraversal(UDUWGraph graph,int startVertex){
     public GraphTraversalVO getDepthFirstTraversal(UDUWGraph graph,int startVertex){
         int nodeNum=graph.getNodeNum();
         int nodeNum=graph.getNodeNum();
-        ArrayList<ArrayList<Integer>> content=new ArrayList<ArrayList<Integer>>();
+        ArrayList<ArrayList<Integer>> content=graph.getContent();
         GraphTraversalVO graphTraversalVO =new GraphTraversalVO();
         GraphTraversalVO graphTraversalVO =new GraphTraversalVO();
         graphTraversalVO.setGraph(graph);
         graphTraversalVO.setGraph(graph);
         ArrayList<GraphTraversalStep> steps=new ArrayList<GraphTraversalStep>();
         ArrayList<GraphTraversalStep> steps=new ArrayList<GraphTraversalStep>();
@@ -157,41 +157,111 @@ public class GraphService {
                 for (int i = 0; i < nodeNum; i++) {
                 for (int i = 0; i < nodeNum; i++) {
                     if (content.get(curVertex).get(i) == 1) {
                     if (content.get(curVertex).get(i) == 1) {
                         if (visited.get(i) == 0) {
                         if (visited.get(i) == 0) {
+                            steps.add(new GraphTraversalStep("tryRoad",curVertex,i,true));
                             nextNode = i;
                             nextNode = i;
+                            steps.add(new GraphTraversalStep("visit",curVertex,i,true));
                             visited.set(nextNode, 1);
                             visited.set(nextNode, 1);
                             visitSequence.add(nextNode);
                             visitSequence.add(nextNode);
                             stack.push(nextNode);
                             stack.push(nextNode);
                             isTerminal = false;
                             isTerminal = false;
                             break;
                             break;
+                        }else{
+                            steps.add(new GraphTraversalStep("tryRoad",curVertex,i,false));
                         }
                         }
                     }
                     }
                 }
                 }
                 if(isTerminal){
                 if(isTerminal){
                     formerNode=stack.pop();
                     formerNode=stack.pop();
+                    steps.add(new GraphTraversalStep("return",curVertex,stack.peek(),true));
                 }
                 }
             }else{ //如果在折返状态中
             }else{ //如果在折返状态中
                 if(formerNode<nodeNum-1) {
                 if(formerNode<nodeNum-1) {
                     boolean needReturn=true;
                     boolean needReturn=true;
                     for (int i = formerNode + 1; i < nodeNum; i++) {
                     for (int i = formerNode + 1; i < nodeNum; i++) {
-                        if(visited.get(i)==0){
-                            stack.push(i);
-                            visited.set(i,1);
-                            visitSequence.add(i);
-                            needReturn=false;
-                            break;
+                        if(content.get(curVertex).get(i)==1) {
+                            if (visited.get(i) == 0) {
+                                steps.add(new GraphTraversalStep("tryRoad",curVertex,i,true));
+                                steps.add(new GraphTraversalStep("visit",curVertex,i,true));
+                                stack.push(i);
+                                visited.set(i, 1);
+                                visitSequence.add(i);
+                                needReturn = false;
+                                break;
+                            }else{
+                                steps.add(new GraphTraversalStep("tryRoad",curVertex,i,false));
+                            }
                         }
                         }
                     }
                     }
                     if(needReturn){
                     if(needReturn){
                         formerNode=stack.pop();
                         formerNode=stack.pop();
+                        if(!stack.isEmpty()) {
+                            steps.add(new GraphTraversalStep("return", curVertex, stack.peek(), true));
+                        }
                     }
                     }
+                }else{ //如果当前分支就是最大分支了,则不用探路直接折返
+                    formerNode=stack.pop();
+                    steps.add(new GraphTraversalStep("return",curVertex,stack.peek(),true));
                 }
                 }
             }
             }
         }
         }
-        return null;
+        graphTraversalVO.setContent(steps);
+        return graphTraversalVO;
     }
     }
     //获取无向带权图的prim算法的最小生成树
     //获取无向带权图的prim算法的最小生成树
-    public PrimMinimumSpanningTree getPrimMinimumSpanningTree(UDUWGraph graph,int startVertex){
-        return null;
+    public PrimMinimumSpanningTree getPrimMinimumSpanningTree(UDWGraph graph,int startVertex){
+        ArrayList<ArrayList<Integer>> content=graph.getContent();
+        int nodeNum=content.size();
+        ArrayList<Integer> cost=new ArrayList<Integer>();
+        ArrayList<Boolean> known=new ArrayList<Boolean>();
+        ArrayList<Integer> startNode=new ArrayList<Integer>();
+        ArrayList<ArrayList<Integer>> treeEdges=new ArrayList<ArrayList<Integer>>();
+        ArrayList<Integer> knownSequence=new ArrayList<Integer>();
+        ArrayList<GraphTraversalStep> steps=new ArrayList<GraphTraversalStep>();
+        PrimMinimumSpanningTree primMinimumSpanningTree=new PrimMinimumSpanningTree();
+        for(int i=0;i<nodeNum;i++){
+            cost.add(Integer.MAX_VALUE);
+            known.add(false);
+            startNode.add(-1);
+        }
+        cost.set(startVertex,0);
+        while(knownSequence.size()<nodeNum){ //还有节点没有被连接
+            int min=Integer.MAX_VALUE;
+            int indexOfMin=-1;
+            for(int i=0;i<nodeNum;i++){
+                if(known.get(i)==false){  //在没有被连接的节点中选一个代价最小的节点
+                    if(cost.get(i)<min){
+                        indexOfMin=i;
+                        min=cost.get(i);
+                    }
+                }
+            }
+            steps.add(new GraphTraversalStep("selectMin",indexOfMin,-1,true));
+            steps.add(new GraphTraversalStep("setKnown",indexOfMin,-1,true));
+            known.set(indexOfMin,true); //连接这个节点,并遍历它周围的节点,若代价更小,则将代价和前驱节点替换
+            knownSequence.add(indexOfMin);
+            for(int i=0;i<nodeNum;i++){
+                if(content.get(indexOfMin).get(i)>0){ //如果有边可以到达的话
+                    steps.add(new GraphTraversalStep("tryRoad",indexOfMin,i,true));
+                    if(content.get(indexOfMin).get(i)<cost.get(i)){ //如果代价更小,需要替换
+                        cost.set(i,content.get(indexOfMin).get(i));
+                        startNode.set(i,indexOfMin);
+                    }
+                }
+            }
+
+        }
+        for(int i=0;i<nodeNum;i++){
+            if(i!=startVertex){
+                ArrayList<Integer> edge=new ArrayList<Integer>();
+                edge.add(startNode.get(i));
+                edge.add(i);
+                treeEdges.add(edge);
+            }
+        }
+        primMinimumSpanningTree.setSteps(steps);
+        primMinimumSpanningTree.setTreeEdges(treeEdges);
+
+        return primMinimumSpanningTree;
     }
     }
 
 
 
 

+ 38 - 0
src/main/java/com/example/data_structure/vo/PrimMinimumSpanningTree.java

@@ -1,4 +1,42 @@
 package com.example.data_structure.vo;
 package com.example.data_structure.vo;
 
 
+import java.util.ArrayList;
+
 public class PrimMinimumSpanningTree {
 public class PrimMinimumSpanningTree {
+    private ArrayList<GraphTraversalStep> steps;
+    private ArrayList<ArrayList<Integer>> treeEdges;
+
+    public PrimMinimumSpanningTree(ArrayList<GraphTraversalStep> steps, ArrayList<ArrayList<Integer>> treeEdges) {
+        this.steps = steps;
+        this.treeEdges = treeEdges;
+    }
+
+    public PrimMinimumSpanningTree() {
+    }
+
+    //getter
+    public ArrayList<GraphTraversalStep> getSteps() {
+        return steps;
+    }
+
+    public ArrayList<ArrayList<Integer>> getTreeEdges() {
+        return treeEdges;
+    }
+
+    //setter
+    public void setSteps(ArrayList<GraphTraversalStep> steps) {
+        this.steps = steps;
+    }
+
+    public void setTreeEdges(ArrayList<ArrayList<Integer>> treeEdges) {
+        this.treeEdges = treeEdges;
+    }
+
+    @Override
+    public String toString() {
+        return "PrimMinimumSpanningTree{" +
+                "steps=" + steps +
+                ", treeEdges=" + treeEdges +
+                '}';
+    }
 }
 }

+ 30 - 0
src/test/java/com/example/data_structure/service/GraphServiceTest.java

@@ -29,6 +29,20 @@ public class GraphServiceTest {
         return new UDUWGraph(content);
         return new UDUWGraph(content);
     }
     }
 
 
+    UDWGraph makeAWGraph(String[] rows){
+        ArrayList<ArrayList<Integer>> content=new ArrayList<ArrayList<Integer>>();
+        for(int i=0;i<rows.length;i++){
+            ArrayList<Integer> arr=new ArrayList<Integer>();
+            String[] row=rows[i].split(" ");
+            for(int j=0;j<row.length;j++){
+                arr.add(Integer.valueOf(row[j]));
+            }
+            content.add(arr);
+        }
+        return new UDWGraph(content);
+    }
+
+
     @Test
     @Test
     void breadthFirstTraversalTest(){
     void breadthFirstTraversalTest(){
         String[] matrix={"0 0 0 1 1 0 0","0 0 0 0 0 0 1","0 0 0 0 1 1 0","1 0 0 0 0 1 0","1 0 1 0 0 0 0","0 0 1 1 0 0 0","0 1 0 0 0 0 0"};
         String[] matrix={"0 0 0 1 1 0 0","0 0 0 0 0 0 1","0 0 0 0 1 1 0","1 0 0 0 0 1 0","1 0 1 0 0 0 0","0 0 1 1 0 0 0","0 1 0 0 0 0 0"};
@@ -36,4 +50,20 @@ public class GraphServiceTest {
         GraphTraversalVO vo=graphService.getBreadthFirstTraversal(graph,0);
         GraphTraversalVO vo=graphService.getBreadthFirstTraversal(graph,0);
         System.out.println(vo.toString());
         System.out.println(vo.toString());
     }
     }
+
+    @Test
+    void depthFirstTraversalTest(){
+        String[] matrix={"0 0 1 1 1 0 0 0","0 0 1 0 0 0 1 0","1 1 0 0 0 1 0 0","1 0 0 0 0 1 0 1","1 0 0 0 0 0 1 1","0 0 1 1 0 0 1 0","0 1 0 0 1 1 0 0","0 0 0 1 1 0 0 0"};
+        UDUWGraph graph=makeAGraph(matrix);
+        GraphTraversalVO vo=graphService.getDepthFirstTraversal(graph,0);
+        System.out.println(vo.toString());
+    }
+
+    @Test
+    void primMinimumSpanningTreeTest(){
+        String[] matrix={"0 0 4 0 0 0 0 0","0 0 8 0 0 8 0 0","4 8 0 0 3 1 6 0","0 0 0 0 0 5 0 8","0 0 3 0 0 0 0 0","0 8 1 5 0 0 7 5","0 0 6 0 0 7 0 0","0 0 0 8 0 5 0 0"};
+        UDWGraph graph=makeAWGraph(matrix);
+        PrimMinimumSpanningTree vo=graphService.getPrimMinimumSpanningTree(graph,0);
+        System.out.println(vo.toString());
+    }
 }
 }