广度优先搜索

来源:互联网 发布:磁条读写器软件 编辑:程序博客网 时间:2024/06/07 16:56

下面算法中,假定输入图G=(V,E)是以邻接链表所标示的。该算法为途中每一个节点赋予了一些额外属性:我们将每个节点u的颜色存放在属性u.color里(白色表示没有发现过的节点,灰色表示已经发现但其邻接节点没有被全部发现,黑色表示已经被发现且邻接节点全部被发现),将u的前驱结点存放在属性u.pi里。如果u没有前驱节点(例如,如果u=s或者节点u尚未被发现),则u.pi = NIL。属性u.d记录的是广度优先搜索算法所计算出的从源节点s到节点u之间的距离。该算法使用了一个先进先出队列Q来管理灰色结点集。

BFS(G,s)1  for each vertex u belong to G.V-{s}2    u.color = WHITE3    r.d = infty4    u.pi = NIL5  s.color = GRAY6  s.d = 07  s.pi = NIL8  Q = emptyset9  ENQUEUE(Q,s)10 while Q != empty11   u = DEQUEUE(Q)12   for each v belong to G.Adj[u]13     if v.color == WHITE14       v.color = GRAY15       v.d = u.d + 116       v.pi = u17       ENQUEUE(Q,v)18   u.color = BLACK

java代码:

    /**     * 广度优先搜索     * @param graphContent     * @param startID     */    @SuppressWarnings("rawtypes")    public static void BFS(String graphContent, int startID){        List<Vertex> vertexs = Route.getVertexs(graphContent);        LinkedList[] list = Route.getLinkedList(graphContent);        for (Vertex vertex : vertexs){            vertex.setColor(Color.WHITE);            vertex.setD(50000);            vertex.setParent(null);        }        Vertex start = Vertex.getVertex(startID);        start.setColor(Color.GRAY);        start.setD(0);        start.setParent(null);        LinkedList<Vertex> Q = new LinkedList<Vertex>();        Q.addLast(start);        while (!Q.isEmpty()){            Vertex u = Q.removeFirst();            for (Object o : list[u.getID()]){                Vertex v = (Vertex)o;                if (v.getColor().equals(Color.WHITE)){                    v.setColor(Color.GRAY);                    v.setD(u.getD() + 1);                    v.setParent(u);                    Q.addLast(v);                }            }            u.setColor(Color.BLACK);        }    }    /**     * 打印最小路径     * @param graphContent     * @param startID     * @param endID     */    public static void print_Path(String graphContent, int startID, int endID){        BFS(graphContent, startID);        Vertex s = Vertex.getVertex(startID);        Vertex v = Vertex.getVertex(endID);        if (v.equals(s)){            System.out.print(s + "--");        }else if (v.getParent() == null){            System.out.println("\nno path from \"s\" to \"v\" exists");        }else {            print_Path(graphContent, startID, v.getParent().getID());            System.out.print(v + "--");        }    }    /**     * 获取邻接链表     * @param graphContent     * @return     */    @SuppressWarnings({ "unchecked", "rawtypes" })    public static LinkedList[] getLinkedList(String graphContent){        List<Vertex> vertexs = getVertexs(graphContent);        LinkedList[] list = new LinkedList[vertexs.size()];        int[] datas = getDatas(graphContent);        for (int i = 0; i < vertexs.size(); i++){            int n = vertexs.get(i).getID();            list[n] = new LinkedList();            list[n].add(vertexs.get(i));            for (int j = 0; j < datas.length/4; j++){                if (vertexs.get(i).equal(datas[j*4+1])){                    list[n].add(Vertex.getVertex(datas[j*4+2]));                }            }        }        return list;    }    /**     * 将图的信息从字符串转换为数字     * @param graphContent     * @return     */    public static int[] getDatas(String graphContent){        String[] strings = graphContent.split("[,\n]");        int[] ans = new int[strings.length];        for (int i = 0; i < ans.length; i++){            ans[i] = Integer.valueOf(strings[i]);        }        return ans;    }    /**     * 获取顶点     * @param graphContent     * @return     */    public static List<Vertex> getVertexs(String graphContent){        int[] datas = getDatas(graphContent);        int n = datas.length/4;        for (int i = 0; i < n; i++){            Vertex.create(datas[i*4+1]);            Vertex.create(datas[i*4+2]);        }        return Vertex.getVertexs();    }

其中graphContent为
0,0,1,1
1,0,2,2
2,0,3,1
3,2,1,3
4,3,1,1
5,2,3,1
6,3,2,1
型字符串,其中每行第一个数为边的编号,第二第三为起点终点编号,第四个数为权值(广度优先搜索没有用到权值)。

0 0