1. 程式人生 > >《演算法》第四章部分程式 part 5

《演算法》第四章部分程式 part 5

▶ 書中第四章部分程式,加上自己補充的程式碼,圖的深度優先遍歷

● 無向圖的廣度優先遍歷,有向 / 無向圖程式碼僅若干方法名不同

  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;
  8
9 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, 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 //assert check(G, s); 25 } 26 27 private
void 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 }