複習一下dfs和bfs 用java

dfs 和 bfs都是用來找從source 到 target的path的算法。

dfs用的是recursion,bfs則用queue。而且bfs可以找出shortest path。

/* tony
 * Apr 28, 2014
 * pathFind gives the edgeTo t from s
 * @pathFind the constructor
 */

public class pathFind{
	private boolean[] marked;
	private int[] edgeTo;
	private int[] distTo;
	//private final int s;
	
	public pathFind(Graph g, int s){
		//this.s = s;
		edgeTo = new int[g.V()];
		distTo = new int[g.V()];
		marked = new boolean[g.V()];
		dfs(g,s);
	}
	
	private void dfs(Graph g, int v){
		marked[v] = true;
		for(int w: g.adj(v)){
			if(!marked[w]){
				edgeTo[w] = v;
				distTo[w] = distTo[v]+1;
				dfs(g,w);
			}
		}
	}

	
	public boolean hasPathTo(int v){
		return marked[v];
	}
	
	
	// pathTo method return an interable value:
	public Iterable<Integer> pathTo(int v){
		if(!hasPathTo(v)){
			return null;
		}
		// else
		Stack<Integer> path = new Stack<Integer>();
		//for(int x = v; x!=s; x = edgeTo[x]){   // why !=s? because I am tracing 
											//back from the node to s
		int x;
		for(x = v; distTo[x]!=0; x = edgeTo[x]){
			path.push(x);
		}
		//path.push(s);
		path.push(x);
		return path;
	}
	
	public static void main(String[] args){
		In in = new In(args[0]);
		Graph g = new Graph(in);
		int s = Integer.parseInt(args[1]);
		pathFind dfs = new pathFind(g,s);
		StdOut.println("DFS path find with distTo output");
		
		for (int v = 0; v < g.V(); v++){
			if(dfs.hasPathTo(v)){
				StdOut.printf("%d to %d - (%d): ", s, v, dfs.distTo[v]);
				for(int x : dfs.pathTo(v)){
					if(x == s) StdOut.print(x);
					else	  StdOut.print("->" + x);
				}
				StdOut.println();
			}
		}
	}
}

這個是bfs:

/*
 * tony
 * Apr 26, 2014
 * BreathFirstPath from Algs4 part II week 1
 * dfs-----recursion----stack
 * bfs-----no recursion----queue
 */

public class BFSPath{
	private static final int INFINITY = Integer.MAX_VALUE;
	private boolean[] marked;
	private int[] edgeTo;
	private int[] distTo;
	
	
	/*
	 * compute the shortest path between a single source vertex
	 */
	public BFSPath(Graph G, int s){
		marked = new boolean[G.V()];
		edgeTo = new int[G.V()];
		distTo = new int[G.V()];
		bfs(G,s);
	}
	
	/*
	 * compute the shortest path between multiple source vertices
	 */
	public BFSPath(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;
		}
		bfs(G, sources);
	}
	
	// bfs 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);
				}
			}
		}
	}
	
	// bfs 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]){
					marked[w] = true;
					distTo[w] = distTo[v]+1;
					edgeTo[w] = v;
					q.enqueue(w);
				}
			}
		}
	}
	
	public boolean hasPathTo(int w){
		return marked[w];
	}
	public int distTo(int w){
		return distTo[w];
	}
	
	public Iterable<Integer> pathTo(int 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;
	}
	
	/**
     * Unit tests the <tt>BreadthFirstPaths</tt> data type.
     */
    public static void main(String[] args) {
        In in = new In(args[0]);
        Graph G = new Graph(in);
        StdOut.println(G);
        StdOut.println("BFS path find output:    ");
        int s = Integer.parseInt(args[1]);
        BFSPath bfs = new BFSPath(G, s);

        for (int v = 0; v < G.V(); v++) {
            if (bfs.hasPathTo(v)) {
                StdOut.printf("%2d to %d (%2d):  ", 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("%2d to %2d (-):  not connected\n", s, v);
            }

        }
    }

	
}

















這個是2個的輸出:

6 vertices, 8 edges 
0: 2 1 5 
1: 0 2 
2: 0 1 3 4 
3: 5 4 2 
4: 3 2 
5: 3 0 


DFS path find with distTo output
0 to 0 - (0): 0
0 to 1 - (2): 0->2->1
0 to 2 - (1): 0->2
0 to 3 - (2): 0->2->3
0 to 4 - (3): 0->2->3->4
0 to 5 - (3): 0->2->3->5


BFS path find output:    
 0 to 0 ( 0):  0
 0 to 1 ( 1):  0->1
 0 to 2 ( 1):  0->2
 0 to 3 ( 2):  0->2->3
 0 to 4 ( 2):  0->2->4
 0 to 5 ( 1):  0->5


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章