▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序、后序和逆后续遍历,以及传递闭包
● 图的前序、后序和逆后续遍历
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.EdgeWeightedDigraph; 7 import edu.princeton.cs.algs4.DirectedEdge; 8 import edu.princeton.cs.algs4.Queue; 9 import edu.princeton.cs.algs4.Stack; 10 11 public class class01 12 { 13 private boolean[] marked; 14 private int[] pre; // 前序顶点列表(索引 -> 顶点) 15 private int[] post; // 后序顶点列表 16 private Queue<Integer> preorder; // 前序队列(顶点) 17 private Queue<Integer> postorder; // 后续队列 18 private int preCounter; // 前序计数器 19 private int postCounter; // 后序计数器 20 21 public class01(Digraph G) 22 { 23 pre = new int[G.V()]; 24 post = new int[G.V()]; 25 postorder = new Queue<Integer>(); 26 preorder = new Queue<Integer>(); 27 marked = new boolean[G.V()]; 28 for (int v = 0; v < G.V(); v++) 29 { 30 if (!marked[v]) 31 dfs(G, v); 32 } 33 } 34 35 public class01(EdgeWeightedDigraph G) 36 { 37 pre = new int[G.V()]; 38 post = new int[G.V()]; 39 postorder = new Queue<Integer>(); 40 preorder = new Queue<Integer>(); 41 marked = new boolean[G.V()]; 42 for (int v = 0; v < G.V(); v++) 43 { 44 if (!marked[v]) 45 dfs(G, v); 46 } 47 } 48 49 private void dfs(Digraph G, int v) 50 { 51 marked[v] = true; 52 pre[v] = preCounter++; // 前序和后序差别在于,将当前顶点加入队列以及递归的先后顺序 53 preorder.enqueue(v); 54 for (int w : G.adj(v)) 55 { 56 if (!marked[w]) 57 dfs(G, w); 58 } 59 postorder.enqueue(v); 60 post[v] = postCounter++; 61 } 62 63 private void dfs(EdgeWeightedDigraph G, int v) 64 { 65 marked[v] = true; 66 pre[v] = preCounter++; 67 preorder.enqueue(v); 68 for (DirectedEdge e : G.adj(v)) 69 { 70 int w = e.to(); 71 if (!marked[w]) 72 dfs(G, w); 73 } 74 postorder.enqueue(v); 75 post[v] = postCounter++; 76 } 77 78 public int pre(int v) 79 { 80 return pre[v]; 81 } 82 83 public int post(int v) 84 { 85 return post[v]; 86 } 87 88 public Iterable<Integer> pre() 89 { 90 return preorder; 91 } 92 93 public Iterable<Integer> post() 94 { 95 return postorder; 96 } 97 98 public Iterable<Integer> reversePost() // 用后续队列生成逆后序栈 99 { 100 Stack<Integer> reverse = new Stack<Integer>(); 101 for (int v : postorder) 102 reverse.push(v); 103 return reverse; 104 } 105 106 public static void main(String[] args) 107 { 108 In in = new In(args[0]); 109 Digraph G = new Digraph(in); 110 class01 dfs = new class01(G); 111 StdOut.println(" v pre post"); 112 StdOut.println("--------------"); 113 for (int v = 0; v < G.V(); v++) 114 StdOut.printf("%4d %4d %4d ", v, dfs.pre(v), dfs.post(v)); 115 116 StdOut.print("Preorder: "); // 分别输出前序、后序和逆后序 117 for (int v : dfs.pre()) 118 StdOut.print(v + " "); 119 StdOut.println(); 120 121 StdOut.print("Postorder: "); 122 for (int v : dfs.post()) 123 StdOut.print(v + " "); 124 StdOut.println(); 125 126 StdOut.print("Reverse postorder: "); 127 for (int v : dfs.reversePost()) 128 StdOut.print(v + " "); 129 StdOut.println(); 130 } 131 }
● 传递闭包
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.DirectedDFS; 7 8 public class class01 9 { 10 private DirectedDFS[] tc; 11 12 public class01(Digraph G) 13 { 14 tc = new DirectedDFS[G.V()]; 15 for (int v = 0; v < G.V(); v++) // 循环尝试从所有点开始深度优先遍历整个图,返回可达点的迭代器 16 tc[v] = new DirectedDFS(G, v); 17 } 18 19 public boolean reachable(int v, int w) 20 { 21 return tc[v].marked(w); 22 } 23 24 public static void main(String[] args) 25 { 26 In in = new In(args[0]); 27 Digraph G = new Digraph(in); 28 class01 tc = new class01(G); 29 30 StdOut.print(" "); 31 for (int v = 0; v < G.V(); v++) 32 StdOut.printf("%3d", v); 33 StdOut.println(" --------------------------------------------"); 34 35 for (int v = 0; v < G.V(); v++) 36 { 37 StdOut.printf("%3d: ", v); 38 for (int w = 0; w < G.V(); w++) 39 StdOut.printf(tc.reachable(v, w) ? " T" : " "); 40 StdOut.println(); 41 } 42 } 43 }