用邻接表实现图的深度优先遍历、广度优先遍历、最短路径(无权图)

Java代码   收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4. import java.util.Stack;  
  5.   
  6. public class Graph {  
  7.   
  8.   
  9.     /**关键字:图 邻接表 深度优先遍历 广度优先遍历 最短路径 
  10.      * key words:Graph Adjacent-list depthFirstVisit breadthFirstVisit getCheapestPath 
  11.      * 1.Graph is a collection of Vertex and Edge. 
  12.      * When you want to implement 'Graph',you deal with two missions:how to implement 'Vertex' and 'Edge' 
  13.      *  a.Vertex: 
  14.      *    Type label-->Vertex's ID,to separate one Vertex from another,like 'A','B',or 0,1,2 
  15.      *    List<Edge> edgeList-->store edges that start with this Vertex. 
  16.      *    ...<output omit> 
  17.      *  b.Edge(as Inner class of Vertex): 
  18.      *    endVertex-->(begin,end),the outer class is 'begin',endVertex is 'end' 
  19.      *    ...<output omit> 
  20.      * 2.In the following,we  
  21.      *  a.use ArrayList to store Vertices 
  22.      *  b.use 'char' as Vertex's ID 
  23.     */  
  24.     private List<Vertex> vertices;  
  25.     private int edgeCount;  
  26.     private List<Vertex> depthFirstResult;  
  27.     private List<Vertex> breadthFirstResult;  
  28.       
  29. public void breadthFirstVisit(char beginLabel){  
  30.           
  31.         Vertex origin=this.getVertexByChar(beginLabel);  
  32.         if(origin==null)return;  
  33.         List<Vertex> queue=new LinkedList<Vertex>();  
  34.         origin.setVisited(true);  
  35.         queue.add(origin);  
  36.         breadthFirstResult.add(origin);  
  37.         Vertex curVertex=null;  
  38.         while(!queue.isEmpty()){  
  39.             curVertex=queue.remove(0);  
  40.             while(curVertex.getFirstUnvisitedNeighbor()!=null){  
  41.                 Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  
  42.                 tmpVertex.setVisited(true);  
  43.                 queue.add(tmpVertex);  
  44.                 breadthFirstResult.add(tmpVertex);  
  45.             }  
  46.               
  47.         }  
  48.         printVertexList(breadthFirstResult);  
  49. }  
  50.       
  51.     public void depthFirstVisit(char beginLabel){  
  52.           
  53.         Vertex origin=this.getVertexByChar(beginLabel);  
  54.         if(origin==null)return;  
  55.         Stack<Vertex> stack=new Stack<Vertex>();  
  56.         origin.setVisited(true);  
  57.         stack.push(origin);  
  58.         depthFirstResult.add(origin);  
  59.         Vertex curVertex=null;  
  60.         while(!stack.isEmpty()){  
  61.             curVertex=stack.peek();  
  62.             Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  
  63.             if(tmpVertex!=null){  
  64.                 tmpVertex.setVisited(true);  
  65.                 depthFirstResult.add(tmpVertex);  
  66.                 stack.push(tmpVertex);  
  67.             }else{  
  68.                 stack.pop();  
  69.             }  
  70.         }  
  71.         printVertexList(depthFirstResult);  
  72.     }  
  73.       
  74.     //getShortestPath.Base on breadthFirstVisit.the edge has no weight.  
  75.     public double getShortestPath(char beginLabel,char endLabel,Stack<Vertex> stack){  
  76.         resetVertices();  
  77.         Vertex begin=this.getVertexByChar(beginLabel);  
  78.         Vertex end=this.getVertexByChar(endLabel);  
  79.         begin.setVisited(true);  
  80.         List<Vertex> queue=new LinkedList<Vertex>();  
  81.         queue.add(begin);  
  82.         boolean done=false;  
  83.         while(!done&&!queue.isEmpty()){  
  84.             Vertex curVertex=queue.remove(0);  
  85.             while(!done&&curVertex.getFirstUnvisitedNeighbor()!=null){  
  86.                 Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  
  87.                 tmpVertex.setVisited(true);  
  88.                 double  tmpCost=curVertex.getCost()+1;  
  89.                 tmpVertex.setPreviousVertex(curVertex);  
  90.                 tmpVertex.setCost(tmpCost);  
  91.                 queue.add(tmpVertex);  
  92.                 if(tmpVertex.equals(end)){  
  93.                     done=true;  
  94.                 }  
  95.             }  
  96.         }  
  97.         double pathLength=end.getCost();  
  98.         //find the path.traverse back from end  
  99.         while(end!=null){  
  100.             stack.push(end);  
  101.             end=end.getPreviousVertex();  
  102.         }  
  103.         return pathLength;  
  104.     }  
  105.       
  106.     public boolean addEdge(char beginLabel,char endLabel,double weight){  
  107.         int beginIndex=vertices.indexOf(new Vertex(beginLabel));  
  108.         int endIndex=vertices.indexOf(new Vertex(endLabel));  
  109.         Vertex beginVertex=vertices.get(beginIndex);  
  110.         Vertex endVertex=vertices.get(endIndex);  
  111.         boolean result=beginVertex.connect(endVertex,weight);  
  112.         edgeCount++;  
  113.         return result;  
  114.     }  
  115.     public boolean addEdge(char beginLabel,char endLabel){  
  116.         return addEdge(beginLabel,endLabel,0);  
  117.     }  
  118.     public boolean addVertex(char label){  
  119.         boolean result=false;  
  120.         Vertex newVertex=new Vertex(label);  
  121.         if(!vertices.contains(newVertex)){  
  122.             vertices.add(newVertex);//reject duplicate vertex  
  123.             result=true;  
  124.         }  
  125.         return result;  
  126.     }  
  127.     public void printVertexList(List<Vertex> list){  
  128.         for(int i=0,len=list.size();i<len;i++){  
  129.             Vertex vertex=list.get(i);  
  130.             System.out.print(vertex.getLabel()+" ");  
  131.         }  
  132.         System.out.println();  
  133.     }  
  134.       
  135.     public void resetVertices(){  
  136.         for(int i=0,len=vertices.size();i<len;i++){  
  137.             Vertex vertex=vertices.get(i);  
  138.             vertex.setPreviousVertex(null);  
  139.             vertex.setVisited(false);  
  140.             vertex.setCost(0);  
  141.         }  
  142.     }  
  143.       
  144.     public Vertex getVertexByChar(char target){  
  145.         Vertex vertex=null;  
  146.         for(int i=0,len=vertices.size();i<len;i++){  
  147.             vertex=vertices.get(i);  
  148.             Character xx=vertex.getLabel();  
  149.             if(xx.charValue()==target){  
  150.                 return vertex;  
  151.             }  
  152.         }  
  153.         return vertex;  
  154.     }  
  155.       
  156.     public Graph(){  
  157.         vertices=new ArrayList<Vertex>();  
  158.         edgeCount=0;  
  159.         depthFirstResult=new ArrayList<Vertex>();  
  160.         breadthFirstResult=new ArrayList<Vertex>();  
  161.     }  
  162.   
  163.       
  164.       
  165.     public static void main(String[] args) {  
  166.           
  167.         Graph graph=createGapth();  
  168.         graph.depthFirstVisit('7');//depthFirstVisit,start with '7'  
  169.         graph.resetVertices();  
  170.         graph.breadthFirstVisit('0');//breadthFirstVisit,start with '0'  
  171.           
  172.         //shortest path  
  173.         Stack<Vertex> pathStack=new Stack<Vertex>();  
  174.         //from '0' to '7'.  
  175.         double pathLength=graph.getShortestPath('0','7',pathStack);  
  176.         System.out.println(pathLength);  
  177.         while(!pathStack.isEmpty()){  
  178.             Vertex vertex=pathStack.pop();  
  179.             System.out.print(vertex.getLabel()+" ");  
  180.         }  
  181.           
  182.         //BasicGraphInterface<String> airMap=new UndirectedGraph<String>();  
  183.         //airMap.  
  184.           
  185.     }  
  186.       
  187.     public static Graph createGapth(){  
  188.         /* 
  189.          0----1---2 
  190.          | \  |   | 
  191.          |  \ |   | 
  192.          |   \|   | 
  193.          3    4   5 
  194.          |   / 
  195.          |  / 
  196.          | / 
  197.          6---7 
  198.          the adjacent List is : 
  199.          0-->4--3--1 
  200.          1-->4--2--0 
  201.          2-->5--1 
  202.          3-->6--0 
  203.          4-->6--1--0 
  204.          5-->2 
  205.          6-->7--4--3 
  206.          7-->6 
  207.          */  
  208.           
  209.         Graph graph=new Graph();  
  210.         graph.addVertex('0');  
  211.         graph.addVertex('1');  
  212.         graph.addVertex('2');  
  213.         graph.addVertex('3');  
  214.         graph.addVertex('4');  
  215.         graph.addVertex('5');  
  216.         graph.addVertex('6');  
  217.         graph.addVertex('7');  
  218.           
  219.         graph.addEdge('0','4');  
  220.         graph.addEdge('0','3');  
  221.         graph.addEdge('0','1');  
  222.           
  223.         graph.addEdge('1','4');  
  224.         graph.addEdge('1','2');  
  225.         graph.addEdge('1','0');  
  226.           
  227.         graph.addEdge('2','5');  
  228.         graph.addEdge('2','1');  
  229.           
  230.         graph.addEdge('3','6');  
  231.         graph.addEdge('3','0');  
  232.           
  233.         graph.addEdge('4','6');  
  234.         graph.addEdge('4','1');  
  235.         graph.addEdge('4','0');  
  236.           
  237.         graph.addEdge('5','2');  
  238.           
  239.         graph.addEdge('6','7');  
  240.         graph.addEdge('6','4');  
  241.         graph.addEdge('6','3');  
  242.           
  243.         graph.addEdge('7','6');  
  244.           
  245.         return graph;  
  246.     }  
  247. }  
  248.   
  249.   
  250. class Vertex{  
  251.     private char label;  
  252.     private List<Edge> edgeList;  
  253.     private boolean isVisited;  
  254.     private Vertex previousVertex;//use it in the method-'getShortestPath()'  
  255.     private double cost;//the cost from beginning to this vertex   
  256.       
  257.     public Vertex(char label){  
  258.         this.label=label;  
  259.         edgeList=new ArrayList<Edge>();  
  260.         isVisited=false;  
  261.         previousVertex=null;  
  262.         cost=0;  
  263.     }  
  264.     public boolean isVisited(){  
  265.         return isVisited;  
  266.     }  
  267.     public void visit(){  
  268.         System.out.println(this.label);  
  269.         this.isVisited=true;  
  270.     }  
  271.       
  272.     public void setPreviousVertex(Vertex vertex){  
  273.         this.previousVertex=vertex;  
  274.     }  
  275.     public void setVisited(Boolean isVisited){  
  276.         this.isVisited=isVisited;  
  277.     }  
  278.     public void setCost(double cost){  
  279.         this.cost=cost;  
  280.     }  
  281.     public Vertex getFirstNeighbor(){  
  282.         Vertex neighbor=this.edgeList.get(0).endVertex;  
  283.         return neighbor;  
  284.     }  
  285.     public char getLabel(){  
  286.         return this.label;  
  287.     }  
  288.       
  289.     public double getCost(){  
  290.         return this.cost;  
  291.     }  
  292.     public Vertex getPreviousVertex(){  
  293.         return this.previousVertex;  
  294.     }  
  295.     public Vertex getFirstUnvisitedNeighbor(){  
  296.         Vertex unVisitedNeighbor=null;  
  297.         for(int i=0,len=edgeList.size();i<len;i++){  
  298.             Vertex vertex=edgeList.get(i).endVertex;  
  299.             if(!vertex.isVisited){  
  300.                 unVisitedNeighbor=vertex;  
  301.                 break;  
  302.             }  
  303.         }  
  304.         return unVisitedNeighbor;  
  305.     }  
  306.     public boolean equals(Object object){  
  307.         boolean result=false;  
  308.         if(this==object)return true;  
  309.         if(object instanceof Vertex){  
  310.             Vertex otherVertex=(Vertex)object;  
  311.             result=this.label==otherVertex.label;  
  312.         }  
  313.         return result;  
  314.     }  
  315.     public boolean connect(Vertex endVertex,double weight){  
  316.           
  317.         boolean result=false;//result=true if successful  
  318.           
  319.         if(!this.equals(endVertex)){//connections should occur in different Vertices  
  320.             boolean isDuplicateEdge=false;  
  321.             List<Edge> edgeList=this.edgeList;  
  322.             if(edgeList.contains(endVertex)){  
  323.                 isDuplicateEdge=true;  
  324.             }  
  325.             if(!isDuplicateEdge){  
  326.                 //endVertex.previousVertex=this;  
  327.                 edgeList.add(new Edge(endVertex,weight));  
  328.                 result=true;  
  329.             }  
  330.         }  
  331.               
  332.         return result;  
  333.     }  
  334.       
  335.     public boolean hasNeighbor(){  
  336.         return !edgeList.isEmpty();  
  337.     }  
  338.     protected  class Edge{  
  339.         //A-->B,then the "outerClass" which invokes the method "getEndVertex"   
  340.         //is "A",the "endVertex" is "B"  
  341.         private Vertex endVertex;  
  342.         private double weight;  
  343.           
  344.         protected Edge(Vertex endVertex,double weight){  
  345.             this.endVertex=endVertex;  
  346.             this.weight=weight;  
  347.         }  
  348.         protected Vertex getEndVertex(){  
  349.             return endVertex;  
  350.         }  
  351.         protected double getWeight(){  
  352.             return weight;  
  353.         }  
  354.           
  355.     }  
  356. }  

你可能感兴趣的:(java,String,object,null,Graph)