《算法》第四章部分程序 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 }

猜你喜欢

转载自www.cnblogs.com/cuancuancuanhao/p/9807789.html