zoukankan      html  css  js  c++  java
  • 深度优先搜索DFS-图

    深度优先搜索的代码:

    public class DepthFirstSearch {
        private boolean[] marked;    // marked[v] = is there an s-v path?
        private int count;           // number of vertices connected to s
    
        public DepthFirstSearch(Graph G, int s) {
            marked = new boolean[G.V()];
            validateVertex(s);
            dfs(G, s);
        }
    
        // depth first search from v
        private void dfs(Graph G, int v) {
            count++;
            marked[v] = true;
            for (int w : G.adj(v)) {
                if (!marked[w]) {
                    dfs(G, w);
                }
            }
        }
        public boolean marked(int v) {
            validateVertex(v);
            return marked[v];
        }
    
    
        public int count() {
            return count;
        }
    
    
        private void validateVertex(int v) {
            int V = marked.length;
            if (v < 0 || v >= V)
                throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
        }
    
    
        public static void main(String[] args) {
            In in = new In(args[0]);
            Graph G = new Graph(in);
            int s = Integer.parseInt(args[1]);
            DepthFirstSearch search = new DepthFirstSearch(G, s);
            for (int v = 0; v < G.V(); v++) {
                if (search.marked(v))
                    StdOut.print(v + " ");
            }
    
            StdOut.println();
            if (search.count() != G.V()) StdOut.println("NOT connected");
            else                         StdOut.println("connected");
        }
    
    }

    深度优先搜索查找图中的路径:

    public class BreadthFirstPaths {
        private static final int INFINITY = Integer.MAX_VALUE;
        private boolean[] marked;  // marked[v] = is there an s-v path
        private int[] edgeTo;      // edgeTo[v] = previous edge on shortest s-v path
        private int[] distTo;      // distTo[v] = number of edges shortest s-v path
    
        /**
         * Computes the shortest path between the source vertex {@code s}
         * and every other vertex in the graph {@code G}.
         * @param G the graph
         * @param s the source vertex
         * @throws IllegalArgumentException unless {@code 0 <= s < V}
         */
        public BreadthFirstPaths(Graph G, int s) {
            marked = new boolean[G.V()];
            distTo = new int[G.V()];
            edgeTo = new int[G.V()];
            validateVertex(s);
            bfs(G, s);
    
            assert check(G, s);
        }
    
        /**
         * Computes the shortest path between any one of the source vertices in {@code sources}
         * and every other vertex in graph {@code G}.
         * @param G the graph
         * @param sources the source vertices
         * @throws IllegalArgumentException if {@code sources} is {@code null}
         * @throws IllegalArgumentException unless {@code 0 <= s < V} for each vertex
         *         {@code s} in {@code sources}
         */
        public BreadthFirstPaths(Graph G, Iterable<Integer> sources) {
            marked = new boolean[G.V()];
            distTo = new int[G.V()];
            edgeTo = new int[G.V()];
            for (int v = 0; v < G.V(); v++)
                distTo[v] = INFINITY;
            validateVertices(sources);
            bfs(G, sources);
        }
    
    
        // breadth-first search from a single source
        private void bfs(Graph G, int s) {
            Queue<Integer> q = new Queue<Integer>();
            for (int v = 0; v < G.V(); v++)
                distTo[v] = INFINITY;
            distTo[s] = 0;
            marked[s] = true;
            q.enqueue(s);
    
            while (!q.isEmpty()) {
                int v = q.dequeue();
                for (int w : G.adj(v)) {
                    if (!marked[w]) {
                        edgeTo[w] = v;
                        distTo[w] = distTo[v] + 1;
                        marked[w] = true;
                        q.enqueue(w);
                    }
                }
            }
        }
    
        // breadth-first search from multiple sources
        private void bfs(Graph G, Iterable<Integer> sources) {
            Queue<Integer> q = new Queue<Integer>();
            for (int s : sources) {
                marked[s] = true;
                distTo[s] = 0;
                q.enqueue(s);
            }
            while (!q.isEmpty()) {
                int v = q.dequeue();
                for (int w : G.adj(v)) {
                    if (!marked[w]) {
                        edgeTo[w] = v;
                        distTo[w] = distTo[v] + 1;
                        marked[w] = true;
                        q.enqueue(w);
                    }
                }
            }
        }
    
        /**
         * Is there a path between the source vertex {@code s} (or sources) and vertex {@code v}?
         * @param v the vertex
         * @return {@code true} if there is a path, and {@code false} otherwise
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         */
        public boolean hasPathTo(int v) {
            validateVertex(v);
            return marked[v];
        }
    
        /**
         * Returns the number of edges in a shortest path between the source vertex {@code s}
         * (or sources) and vertex {@code v}?
         * @param v the vertex
         * @return the number of edges in a shortest path
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         */
        public int distTo(int v) {
            validateVertex(v);
            return distTo[v];
        }
    
        /**
         * Returns a shortest path between the source vertex {@code s} (or sources)
         * and {@code v}, or {@code null} if no such path.
         * @param  v the vertex
         * @return the sequence of vertices on a shortest path, as an Iterable
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         */
        public Iterable<Integer> pathTo(int v) {
            validateVertex(v);
            if (!hasPathTo(v)) return null;
            Stack<Integer> path = new Stack<Integer>();
            int x;
            for (x = v; distTo[x] != 0; x = edgeTo[x])
                path.push(x);
            path.push(x);
            return path;
        }
    
    
        // check optimality conditions for single source
        private boolean check(Graph G, int s) {
    
            // check that the distance of s = 0
            if (distTo[s] != 0) {
                StdOut.println("distance of source " + s + " to itself = " + distTo[s]);
                return false;
            }
    
            // check that for each edge v-w dist[w] <= dist[v] + 1
            // provided v is reachable from s
            for (int v = 0; v < G.V(); v++) {
                for (int w : G.adj(v)) {
                    if (hasPathTo(v) != hasPathTo(w)) {
                        StdOut.println("edge " + v + "-" + w);
                        StdOut.println("hasPathTo(" + v + ") = " + hasPathTo(v));
                        StdOut.println("hasPathTo(" + w + ") = " + hasPathTo(w));
                        return false;
                    }
                    if (hasPathTo(v) && (distTo[w] > distTo[v] + 1)) {
                        StdOut.println("edge " + v + "-" + w);
                        StdOut.println("distTo[" + v + "] = " + distTo[v]);
                        StdOut.println("distTo[" + w + "] = " + distTo[w]);
                        return false;
                    }
                }
            }
    
            // check that v = edgeTo[w] satisfies distTo[w] = distTo[v] + 1
            // provided v is reachable from s
            for (int w = 0; w < G.V(); w++) {
                if (!hasPathTo(w) || w == s) continue;
                int v = edgeTo[w];
                if (distTo[w] != distTo[v] + 1) {
                    StdOut.println("shortest path edge " + v + "-" + w);
                    StdOut.println("distTo[" + v + "] = " + distTo[v]);
                    StdOut.println("distTo[" + w + "] = " + distTo[w]);
                    return false;
                }
            }
    
            return true;
        }
    
        // throw an IllegalArgumentException unless {@code 0 <= v < V}
        private void validateVertex(int v) {
            int V = marked.length;
            if (v < 0 || v >= V)
                throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
        }
    
        // throw an IllegalArgumentException unless {@code 0 <= v < V}
        private void validateVertices(Iterable<Integer> vertices) {
            if (vertices == null) {
                throw new IllegalArgumentException("argument is null");
            }
            for (Integer v : vertices) {
                if (v == null) {
                    throw new IllegalArgumentException("vertex is null");
                }
                validateVertex(v);
            }
        }
    
        /**
         * Unit tests the {@code BreadthFirstPaths} data type.
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
            In in = new In(args[0]);
            Graph G = new Graph(in);
            // StdOut.println(G);
    
            int s = Integer.parseInt(args[1]);
            BreadthFirstPaths bfs = new BreadthFirstPaths(G, s);
    
            for (int v = 0; v < G.V(); v++) {
                if (bfs.hasPathTo(v)) {
                    StdOut.printf("%d to %d (%d):  ", s, v, bfs.distTo(v));
                    for (int x : bfs.pathTo(v)) {
                        if (x == s) StdOut.print(x);
                        else        StdOut.print("-" + x);
                    }
                    StdOut.println();
                }
    
                else {
                    StdOut.printf("%d to %d (-):  not connected
    ", s, v);
                }
    
            }
        }
    
    
    }
  • 相关阅读:
    员工看公司
    Java多线程
    Intellij热部署插件JRebel的详细配置及图解
    Java并发处理锁 Lock
    Java8 Stream
    Eclipse下Maven安装和配置
    IntelliJ IDEA 部署Tomcat及创建一个web工程
    IntelliJ IDEA 下搭建vue项目工程
    Vue Router路由管理器介绍
    用WebStorm搭建vue项目
  • 原文地址:https://www.cnblogs.com/hequnwang/p/14301922.html
Copyright © 2011-2022 走看看