zoukankan      html  css  js  c++  java
  • 《算法》第四章部分程序 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
    ", s, v);
    106         }
    107         if (search.count() != G.V())
    108             StdOut.println("
    Not connected.
    ");
    109         else
    110             StdOut.println("
    Connected.
    ");
    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
    ", s, v);
    106         }
    107         if (search.count() != G.V())
    108             StdOut.println("
    Not connected.
    ");
    109         else
    110             StdOut.println("
    Connected.
    ");
    111     }
    112 }
  • 相关阅读:
    Android中AsyncTask与handler
    AndroidTimer使用(三)补充篇
    Android的消息机制(一)
    Android消息处理机制(二)
    java操作Excel文件(二)
    java操作excel
    Android APK反编译详解(附图)
    Android中Handler的使用方法——在子线程中更新界面
    Android线程间通信的Message机制
    AndroidTimer使用(二)
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9807780.html
Copyright © 2011-2022 走看看