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


    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序、后序和逆后续遍历,以及传递闭包

    ● 图的前序、后序和逆后续遍历

      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 }
  • 相关阅读:
    Linux C 使用 libmaxminddb 读取 GeoIP2 MMDB 获取 IP 的地理位置
    同时装了 Python 3 和 Python 2,怎么用 pip ?
    Linux C Socket 编程
    Shell 筛选符合条件的 ELF 文件
    Linux C 获取本机所有网卡的 IP,Mask
    【转载】VirtualBox 扩展增强包安装
    Linux 下 GCC 的使用
    Linux 基础
    MobaXterm 连接 VirtualBox 6 虚拟机中的 CentOS 7
    ruby使用ocra打包exe文件,,报错libssp-0.dll
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9830114.html
Copyright © 2020-2023  润新知