《算法》第四章部分程序 part 4

▶ 书中第四章部分程序,加上自己补充的代码,图的深度优先遍历

● 无向图的深度优先遍历,有向 / 无向图代码仅若干方法名不同,包括递归和非递归版本,去掉了顶点有效性的检查

  1 package package01;
  2 
  3 import java.util.Iterator;              // nonRecursiveDFS 需要
  4 import edu.princeton.cs.algs4.In;
  5 import edu.princeton.cs.algs4.StdOut;
  6 import edu.princeton.cs.algs4.Graph;
  7 import edu.princeton.cs.algs4.Stack;    // recursiveDFS 不用
  8 
  9 public class class01
 10 {
 11     private final int s;                // 根顶点,depthFirstPath 需要
 12     private boolean[] marked;           // 顶点是否已被遍历
 13     private int count;                  // 已遍历的顶点数(含后退),即从 s 可达的顶点数,depthFirstPath 不用
 14     private int[] edgeTo;               // 每个顶点在 s - v 路径中的父顶点,depthFirstPath 需要
 15 
 16     public class01(Graph G, int inputS) // 初始化,开始DFS
 17     {
 18         s = inputS;
 19         marked = new boolean[G.V()];
 20         edgeTo = new int[G.V()];
 21         recursiveDFS(G, s);
 22     }
 23 
 24     private void recursiveDFS(Graph G, int v)
 25     {
 26         count++;
 27         marked[v] = true;
 28         for (int w : G.adj(v))
 29         {
 30             if (!marked[w])
 31             {
 32                 edgeTo[w] = v;          //  depthFirstPath 需要
 33                 recursiveDFS(G, w);
 34             }
 35         }
 36     }
 37 
 38     public void nonRecursiveDFS(Graph G, int s)     // 非递归版本
 39     {
 40         marked = new boolean[G.V()];
 41         Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];// 记录每个顶点处已经遍历到了哪一个链表节点
 42         for (int v = 0; v < G.V(); v++)
 43             adj[v] = G.adj(v).iterator();
 44         Stack<Integer> stack = new Stack<Integer>();
 45         marked[s] = true;
 46         for (stack.push(s); !stack.isEmpty();)
 47         {
 48             int v = stack.peek();
 49             if (adj[v].hasNext())
 50             {
 51                 int w = adj[v].next();
 52                 if (!marked[w])
 53                 {
 54                     marked[w] = true;
 55                     stack.push(w);
 56                 }
 57             }
 58             else
 59                 stack.pop();
 60         }
 61     }
 62 
 63     public boolean marked(int v)
 64     {
 65         return marked[v];
 66     }
 67 
 68     public int count()
 69     {
 70         return count;
 71     }
 72 
 73     public Iterable<Integer> pathTo(int v)
 74     {
 75         if (!hasPathTo(v))
 76             return null;
 77         Stack<Integer> path = new Stack<Integer>();
 78         for (int x = v; x != s; x = edgeTo[x])      // 从终点向起点压栈,以后吐栈的时候就是从起点到终点
 79             path.push(x);
 80         path.push(s);
 81         return path;
 82     }
 83 
 84     public static void main(String[] args)
 85     {
 86         In in = new In(args[0]);                    // 读入图文件和遍历起点
 87         int s = Integer.parseInt(args[1]);
 88         Graph G = new Graph(in);
 89         class01 search = new class01(G, s);
 90         for (int v = 0; v < G.V(); v++)             // 通过检查是否所有的点都被遍历来确定图是否连通
 91         {
 92             if (search.marked(v))
 93             {
 94                 StdOut.printf("%d to %d:  ", s, v);
 95                 for (int x : search.pathTo(v))
 96                 {
 97                     if (x == s)
 98                         StdOut.print(x);
 99                     else
100                         StdOut.print("-" + x);
101                 }
102                 StdOut.println();
103             }
104             else
105                 StdOut.printf("%d to %d: not connected\n", s, v);
106         }
107         if (search.count() != G.V())
108             StdOut.println("\nNot connected.\n");
109         else
110             StdOut.println("\nConnected.\n");
111     }
112 }

● 有向图的深度优先遍历

  1 package package01;
  2 
  3 import java.util.Iterator;
  4 import edu.princeton.cs.algs4.In;
  5 import edu.princeton.cs.algs4.StdOut;
  6 import edu.princeton.cs.algs4.Digraph;
  7 import edu.princeton.cs.algs4.Stack;
  8 
  9 public class class01
 10 {
 11     private final int s;                
 12     private boolean[] marked;
 13     private int count;
 14     private int[] edgeTo;               
 15 
 16     public class01(Digraph G, int inputS)
 17     {
 18         s = inputS;
 19         marked = new boolean[G.V()];
 20         edgeTo = new int[G.V()];
 21         recursiveDirectedDFS(G, s);
 22     }
 23 
 24     private void recursiveDirectedDFS(Digraph G, int v)
 25     {
 26         count++;
 27         marked[v] = true;
 28         for (int w : G.adj(v))
 29         {
 30             if (!marked[w])
 31             {
 32                 edgeTo[w] = v;
 33                 recursiveDirectedDFS(G, w);
 34             }
 35         }
 36     }
 37 
 38     public void nonRecursiveDirectedDFS(Digraph G, int s)
 39     {
 40         marked = new boolean[G.V()];
 41         Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];
 42         for (int v = 0; v < G.V(); v++)
 43             adj[v] = G.adj(v).iterator();
 44         Stack<Integer> stack = new Stack<Integer>();
 45         marked[s] = true;
 46         for (stack.push(s); !stack.isEmpty();)
 47         {
 48             int v = stack.peek();
 49             if (adj[v].hasNext())
 50             {
 51                 int w = adj[v].next();
 52                 if (!marked[w])
 53                 {
 54                     marked[w] = true;
 55                     stack.push(w);
 56                 }
 57             }
 58             else
 59                 stack.pop();
 60         }
 61     }
 62 
 63     public boolean marked(int v)
 64     {
 65         return marked[v];
 66     }
 67 
 68     public int count()
 69     {
 70         return count;
 71     }
 72 
 73     public Iterable<Integer> pathTo(int v)
 74     {
 75         if (!hasPathTo(v))
 76             return null;
 77         Stack<Integer> path = new Stack<Integer>();
 78         for (int x = v; x != s; x = edgeTo[x])
 79             path.push(x);
 80         path.push(s);
 81         return path;
 82     }
 83 
 84     public static void main(String[] args)
 85     {
 86         In in = new In(args[0]);
 87         int s = Integer.parseInt(args[1]);
 88         Graph G = new Graph(in);        
 89         class01 search = new class01(G, s);
 90         for (int v = 0; v < G.V(); v++)
 91         {
 92             if (search.marked(v))
 93             {
 94                 StdOut.printf("%d to %d:  ", s, v);
 95                 for (int x : search.pathTo(v))
 96                 {
 97                     if (x == s)
 98                         StdOut.print(x);
 99                     else
100                         StdOut.print("-" + x);
101                 }
102                 StdOut.println();
103             }
104             else
105                 StdOut.printf("%d to %d: not connected\n", s, v);
106         }
107         if (search.count() != G.V())
108             StdOut.println("\nNot connected.\n");
109         else
110             StdOut.println("\nConnected.\n");
111     }
112 }

猜你喜欢

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