您的位置:首页 > 移动开发 > Objective-C

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

2012-09-14 21:26 786 查看
Java代码  



import java.util.ArrayList;  

import java.util.LinkedList;  

import java.util.List;  

import java.util.Stack;  

  

public class Graph {  

  

  

    /**关键字:图 邻接表 深度优先遍历 广度优先遍历 最短路径 

     * key words:Graph Adjacent-list depthFirstVisit breadthFirstVisit getCheapestPath 

     * 1.Graph is a collection of Vertex and Edge. 

     * When you want to implement 'Graph',you deal with two missions:how to implement 'Vertex' and 'Edge' 

     *  a.Vertex: 

     *    Type label-->Vertex's ID,to separate one Vertex from another,like 'A','B',or 0,1,2 

     *    List<Edge> edgeList-->store edges that start with this Vertex. 

     *    ...<output omit> 

     *  b.Edge(as Inner class of Vertex): 

     *    endVertex-->(begin,end),the outer class is 'begin',endVertex is 'end' 

     *    ...<output omit> 

     * 2.In the following,we  

     *  a.use ArrayList to store Vertices 

     *  b.use 'char' as Vertex's ID 

    */  

    private List<Vertex> vertices;  

    private int edgeCount;  

    private List<Vertex> depthFirstResult;  

    private List<Vertex> breadthFirstResult;  

      

public void breadthFirstVisit(char beginLabel){  

          

        Vertex origin=this.getVertexByChar(beginLabel);  

        if(origin==null)return;  

        List<Vertex> queue=new LinkedList<Vertex>();  

        origin.setVisited(true);  

        queue.add(origin);  

        breadthFirstResult.add(origin);  

        Vertex curVertex=null;  

        while(!queue.isEmpty()){  

            curVertex=queue.remove(0);  

            while(curVertex.getFirstUnvisitedNeighbor()!=null){  

                Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  

                tmpVertex.setVisited(true);  

                queue.add(tmpVertex);  

                breadthFirstResult.add(tmpVertex);  

            }  

              

        }  

        printVertexList(breadthFirstResult);  

}  

      

    public void depthFirstVisit(char beginLabel){  

          

        Vertex origin=this.getVertexByChar(beginLabel);  

        if(origin==null)return;  

        Stack<Vertex> stack=new Stack<Vertex>();  

        origin.setVisited(true);  

        stack.push(origin);  

        depthFirstResult.add(origin);  

        Vertex curVertex=null;  

        while(!stack.isEmpty()){  

            curVertex=stack.peek();  

            Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  

            if(tmpVertex!=null){  

                tmpVertex.setVisited(true);  

                depthFirstResult.add(tmpVertex);  

                stack.push(tmpVertex);  

            }else{  

                stack.pop();  

            }  

        }  

        printVertexList(depthFirstResult);  

    }  

      

    //getShortestPath.Base on breadthFirstVisit.the edge has no weight.  

    public double getShortestPath(char beginLabel,char endLabel,Stack<Vertex> stack){  

        resetVertices();  

        Vertex begin=this.getVertexByChar(beginLabel);  

        Vertex end=this.getVertexByChar(endLabel);  

        begin.setVisited(true);  

        List<Vertex> queue=new LinkedList<Vertex>();  

        queue.add(begin);  

        boolean done=false;  

        while(!done&&!queue.isEmpty()){  

            Vertex curVertex=queue.remove(0);  

            while(!done&&curVertex.getFirstUnvisitedNeighbor()!=null){  

                Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();  

                tmpVertex.setVisited(true);  

                double  tmpCost=curVertex.getCost()+1;  

                tmpVertex.setPreviousVertex(curVertex);  

                tmpVertex.setCost(tmpCost);  

                queue.add(tmpVertex);  

                if(tmpVertex.equals(end)){  

                    done=true;  

                }  

            }  

        }  

        double pathLength=end.getCost();  

        //find the path.traverse back from end  

        while(end!=null){  

            stack.push(end);  

            end=end.getPreviousVertex();  

        }  

        return pathLength;  

    }  

      

    public boolean addEdge(char beginLabel,char endLabel,double weight){  

        int beginIndex=vertices.indexOf(new Vertex(beginLabel));  

        int endIndex=vertices.indexOf(new Vertex(endLabel));  

        Vertex beginVertex=vertices.get(beginIndex);  

        Vertex endVertex=vertices.get(endIndex);  

        boolean result=beginVertex.connect(endVertex,weight);  

        edgeCount++;  

        return result;  

    }  

    public boolean addEdge(char beginLabel,char endLabel){  

        return addEdge(beginLabel,endLabel,0);  

    }  

    public boolean addVertex(char label){  

        boolean result=false;  

        Vertex newVertex=new Vertex(label);  

        if(!vertices.contains(newVertex)){  

            vertices.add(newVertex);//reject duplicate vertex  

            result=true;  

        }  

        return result;  

    }  

    public void printVertexList(List<Vertex> list){  

        for(int i=0,len=list.size();i<len;i++){  

            Vertex vertex=list.get(i);  

            System.out.print(vertex.getLabel()+" ");  

        }  

        System.out.println();  

    }  

      

    public void resetVertices(){  

        for(int i=0,len=vertices.size();i<len;i++){  

            Vertex vertex=vertices.get(i);  

            vertex.setPreviousVertex(null);  

            vertex.setVisited(false);  

            vertex.setCost(0);  

        }  

    }  

      

    public Vertex getVertexByChar(char target){  

        Vertex vertex=null;  

        for(int i=0,len=vertices.size();i<len;i++){  

            vertex=vertices.get(i);  

            Character xx=vertex.getLabel();  

            if(xx.charValue()==target){  

                return vertex;  

            }  

        }  

        return vertex;  

    }  

      

    public Graph(){  

        vertices=new ArrayList<Vertex>();  

        edgeCount=0;  

        depthFirstResult=new ArrayList<Vertex>();  

        breadthFirstResult=new ArrayList<Vertex>();  

    }  

  

      

      

    public static void main(String[] args) {  

          

        Graph graph=createGapth();  

        graph.depthFirstVisit('7');//depthFirstVisit,start with '7'  

        graph.resetVertices();  

        graph.breadthFirstVisit('0');//breadthFirstVisit,start with '0'  

          

        //shortest path  

        Stack<Vertex> pathStack=new Stack<Vertex>();  

        //from '0' to '7'.  

        double pathLength=graph.getShortestPath('0','7',pathStack);  

        System.out.println(pathLength);  

        while(!pathStack.isEmpty()){  

            Vertex vertex=pathStack.pop();  

            System.out.print(vertex.getLabel()+" ");  

        }  

          

        //BasicGraphInterface<String> airMap=new UndirectedGraph<String>();  

        //airMap.  

          

    }  

      

    public static Graph createGapth(){  

        /* 

         0----1---2 

         | \  |   | 

         |  \ |   | 

         |   \|   | 

         3    4   5 

         |   / 

         |  / 

         | / 

         6---7 

         the adjacent List is : 

         0-->4--3--1 

         1-->4--2--0 

         2-->5--1 

         3-->6--0 

         4-->6--1--0 

         5-->2 

         6-->7--4--3 

         7-->6 

         */  

          

        Graph graph=new Graph();  

        graph.addVertex('0');  

        graph.addVertex('1');  

        graph.addVertex('2');  

        graph.addVertex('3');  

        graph.addVertex('4');  

        graph.addVertex('5');  

        graph.addVertex('6');  

        graph.addVertex('7');  

          

        graph.addEdge('0','4');  

        graph.addEdge('0','3');  

        graph.addEdge('0','1');  

          

        graph.addEdge('1','4');  

        graph.addEdge('1','2');  

        graph.addEdge('1','0');  

          

        graph.addEdge('2','5');  

        graph.addEdge('2','1');  

          

        graph.addEdge('3','6');  

        graph.addEdge('3','0');  

          

        graph.addEdge('4','6');  

        graph.addEdge('4','1');  

        graph.addEdge('4','0');  

          

        graph.addEdge('5','2');  

          

        graph.addEdge('6','7');  

        graph.addEdge('6','4');  

        graph.addEdge('6','3');  

          

        graph.addEdge('7','6');  

          

        return graph;  

    }  

}  

  

  

class Vertex{  

    private char label;  

    private List<Edge> edgeList;  

    private boolean isVisited;  

    private Vertex previousVertex;//use it in the method-'getShortestPath()'  

    private double cost;//the cost from beginning to this vertex   

      

    public Vertex(char label){  

        this.label=label;  

        edgeList=new ArrayList<Edge>();  

        isVisited=false;  

        previousVertex=null;  

        cost=0;  

    }  

    public boolean isVisited(){  

        return isVisited;  

    }  

    public void visit(){  

        System.out.println(this.label);  

        this.isVisited=true;  

    }  

      

    public void setPreviousVertex(Vertex vertex){  

        this.previousVertex=vertex;  

    }  

    public void setVisited(Boolean isVisited){  

        this.isVisited=isVisited;  

    }  

    public void setCost(double cost){  

        this.cost=cost;  

    }  

    public Vertex getFirstNeighbor(){  

        Vertex neighbor=this.edgeList.get(0).endVertex;  

        return neighbor;  

    }  

    public char getLabel(){  

        return this.label;  

    }  

      

    public double getCost(){  

        return this.cost;  

    }  

    public Vertex getPreviousVertex(){  

        return this.previousVertex;  

    }  

    public Vertex getFirstUnvisitedNeighbor(){  

        Vertex unVisitedNeighbor=null;  

        for(int i=0,len=edgeList.size();i<len;i++){  

            Vertex vertex=edgeList.get(i).endVertex;  

            if(!vertex.isVisited){  

                unVisitedNeighbor=vertex;  

                break;  

            }  

        }  

        return unVisitedNeighbor;  

    }  

    public boolean equals(Object object){  

        boolean result=false;  

        if(this==object)return true;  

        if(object instanceof Vertex){  

            Vertex otherVertex=(Vertex)object;  

            result=this.label==otherVertex.label;  

        }  

        return result;  

    }  

    public boolean connect(Vertex endVertex,double weight){  

          

        boolean result=false;//result=true if successful  

          

        if(!this.equals(endVertex)){//connections should occur in different Vertices  

            boolean isDuplicateEdge=false;  

            List<Edge> edgeList=this.edgeList;  

            if(edgeList.contains(endVertex)){  

                isDuplicateEdge=true;  

            }  

            if(!isDuplicateEdge){  

                //endVertex.previousVertex=this;  

                edgeList.add(new Edge(endVertex,weight));  

                result=true;  

            }  

        }  

              

        return result;  

    }  

      

    public boolean hasNeighbor(){  

        return !edgeList.isEmpty();  

    }  

    protected  class Edge{  

        //A-->B,then the "outerClass" which invokes the method "getEndVertex"   

        //is "A",the "endVertex" is "B"  

        private Vertex endVertex;  

        private double weight;  

          

        protected Edge(Vertex endVertex,double weight){  

            this.endVertex=endVertex;  

            this.weight=weight;  

        }  

        protected Vertex getEndVertex(){  

            return endVertex;  

        }  

        protected double getWeight(){  

            return weight;  

        }  

          

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null graph object string java
相关文章推荐