《演算法》第四章部分程式 part 5
阿新 • • 發佈:2018-11-11
▶ 書中第四章部分程式,加上自己補充的程式碼,圖的深度優先遍歷
● 無向圖的廣度優先遍歷,有向 / 無向圖程式碼僅若干方法名不同
1 package package01; 2 3 import edu.princeton.cs.algs4.In; 4 import edu.princeton.cs.algs4.StdOut; 5 import edu.princeton.cs.algs4.Graph; 6 import edu.princeton.cs.algs4.Stack; 7 import edu.princeton.cs.algs4.Queue; 89 public class class01 10 { 11 private static final int INFINITY = Integer.MAX_VALUE; 12 private boolean[] marked; // 頂點是否已被遍歷 13 private int[] edgeTo; // 每個頂點在 s - v 路徑中的父頂點 14 private int[] distTo; // 每個頂點在 s - v 路徑中的路徑長 15 16 public class01(Graph G, ints) 17 { 18 marked = new boolean[G.V()]; 19 distTo = new int[G.V()]; 20 edgeTo = new int[G.V()]; 21 for (int v = 0; v < G.V(); v++) 22 distTo[v] = INFINITY; 23 nonRecursiveBFS(G, s); 24 //assert check(G, s); 25 } 26 27 privatevoid nonRecursiveBFS(Graph G, int s) 28 { 29 Queue<Integer> q = new Queue<Integer>(); 30 distTo[s] = 0; 31 marked[s] = true; 32 for (q.enqueue(s); !q.isEmpty();) 33 { 34 int v = q.dequeue(); 35 for (int w : G.adj(v)) 36 { 37 if (!marked[w]) 38 { 39 edgeTo[w] = v; 40 distTo[w] = distTo[v] + 1; 41 marked[w] = true; 42 q.enqueue(w); 43 } 44 } 45 } 46 } 47 48 private void nonRecursiveBFS(Graph G, Iterable<Integer> sources) // 以迭代器元素為起點列表進行遍歷 49 { 50 Queue<Integer> q = new Queue<Integer>(); 51 for (int s : sources) 52 { 53 marked[s] = true; 54 distTo[s] = 0; 55 q.enqueue(s); 56 } 57 for (;!q.isEmpty();) 58 { 59 int v = q.dequeue(); 60 for (int w : G.adj(v)) 61 { 62 if (!marked[w]) 63 { 64 edgeTo[w] = v; 65 distTo[w] = distTo[v] + 1; 66 marked[w] = true; 67 q.enqueue(w); 68 } 69 } 70 } 71 } 72 73 public boolean marked(int v) 74 { 75 return marked[v]; 76 } 77 78 public int distTo(int v) 79 { 80 return distTo[v]; 81 } 82 83 public Iterable<Integer> pathTo(int v) 84 { 85 if (!marked(v)) 86 return null; 87 Stack<Integer> path = new Stack<Integer>(); 88 int x; 89 for (x = v; distTo[x] != 0; x = edgeTo[x]) 90 path.push(x); 91 path.push(x); 92 return path; 93 } 94 95 private boolean check(Graph G, int s) 96 { 97 if (distTo[s] != 0) 98 { 99 StdOut.println("\n<check> error distance of s.\n"); 100 return false; 101 } 102 for (int v = 0; v < G.V(); v++) 103 { 104 for (int w : G.adj(v)) 105 { 106 if (marked(v) != marked(w)) // 檢查邊正確性 107 { 108 StdOut.println("edge " + v + "-" + w); 109 StdOut.println("marked(" + v + ") = " + marked(v)); 110 StdOut.println("marked(" + w + ") = " + marked(w)); 111 return false; 112 } 113 if (marked(v) && (distTo[w] > distTo[v] + 1)) // 檢查頂點 v 相連的頂點的距離正確性 114 { 115 StdOut.println("edge " + v + "-" + w); 116 StdOut.println("distTo[" + v + "] = " + distTo[v]); 117 StdOut.println("distTo[" + w + "] = " + distTo[w]); 118 return false; 119 } 120 } 121 } 122 for (int w = 0; w < G.V(); w++) 123 { 124 if (!marked(w) || w == s) 125 continue; 126 int v = edgeTo[w]; 127 if (distTo[w] != distTo[v] + 1) // 逐邊檢查距離正確性 128 { 129 StdOut.println("shortest path edge " + v + "-" + w); 130 StdOut.println("distTo[" + v + "] = " + distTo[v]); 131 StdOut.println("distTo[" + w + "] = " + distTo[w]); 132 return false; 133 } 134 } 135 return true; 136 } 137 138 public static void main(String[] args) 139 { 140 In in = new In(args[0]); 141 int s = Integer.parseInt(args[1]); 142 Graph G = new Graph(in); 143 class01 search = new class01(G, s); 144 for (int v = 0; v < G.V(); v++) 145 { 146 if (search.marked(v)) 147 { 148 StdOut.printf("%d to %d (%d): ", s, v, search.distTo(v)); 149 for (int x : search.pathTo(v)) 150 { 151 if (x == s) 152 StdOut.print(x); 153 else 154 StdOut.print("-" + x); 155 } 156 StdOut.println(); 157 } 158 else 159 StdOut.printf("%d to %d (-): not connected\n", s, v); 160 } 161 } 162 }
● 有向圖廣度優先遍歷
1 package package01; 2 3 import edu.princeton.cs.algs4.In; 4 import edu.princeton.cs.algs4.StdOut; 5 import edu.princeton.cs.algs4.Digraph; 6 import edu.princeton.cs.algs4.Stack; 7 import edu.princeton.cs.algs4.Queue; 8 9 public class class01 10 { 11 private static final int INFINITY = Integer.MAX_VALUE; 12 private boolean[] marked; 13 private int[] edgeTo; 14 private int[] distTo; 15 16 public class01(Digraph G, int s) 17 { 18 marked = new boolean[G.V()]; 19 distTo = new int[G.V()]; 20 edgeTo = new int[G.V()]; 21 for (int v = 0; v < G.V(); v++) 22 distTo[v] = INFINITY; 23 nonRecursiveBFS(G, s); 24 } 25 26 private void nonRecursiveBFS(Digraph G, int s) 27 { 28 Queue<Integer> q = new Queue<Integer>(); 29 distTo[s] = 0; 30 marked[s] = true; 31 for (q.enqueue(s); !q.isEmpty();) 32 { 33 int v = q.dequeue(); 34 for (int w : G.adj(v)) 35 { 36 if (!marked[w]) 37 { 38 edgeTo[w] = v; 39 distTo[w] = distTo[v] + 1; 40 marked[w] = true; 41 q.enqueue(w); 42 } 43 } 44 } 45 } 46 47 private void nonRecursiveBFS(Digraph G, Iterable<Integer> sources) 48 { 49 Queue<Integer> q = new Queue<Integer>(); 50 for (int s : sources) 51 { 52 marked[s] = true; 53 distTo[s] = 0; 54 q.enqueue(s); 55 } 56 for (;!q.isEmpty();) 57 { 58 int v = q.dequeue(); 59 for (int w : G.adj(v)) 60 { 61 if (!marked[w]) 62 { 63 edgeTo[w] = v; 64 distTo[w] = distTo[v] + 1; 65 marked[w] = true; 66 q.enqueue(w); 67 } 68 } 69 } 70 } 71 72 public boolean marked(int v) 73 { 74 return marked[v]; 75 } 76 77 public int distTo(int v) 78 { 79 return distTo[v]; 80 } 81 82 public Iterable<Integer> pathTo(int v) 83 { 84 if (!marked(v)) 85 return null; 86 Stack<Integer> path = new Stack<Integer>(); 87 int x; 88 for (x = v; distTo[x] != 0; x = edgeTo[x]) 89 path.push(x); 90 path.push(x); 91 return path; 92 } 93 94 public static void main(String[] args) 95 { 96 In in = new In(args[0]); 97 int s = Integer.parseInt(args[1]); 98 Digraph G = new Digraph(in); 99 class01 search = new class01(G, s); 100 for (int v = 0; v < G.V(); v++) 101 { 102 if (search.marked(v)) 103 { 104 StdOut.printf("%d to %d (%d): ", s, v, search.distTo(v)); 105 for (int x : search.pathTo(v)) 106 { 107 if (x == s) 108 StdOut.print(x); 109 else 110 StdOut.print("->" + x); 111 } 112 StdOut.println(); 113 } 114 else 115 StdOut.printf("%d to %d (-): not connected\n", s, v); 116 } 117 } 118 }