zoukankan      html  css  js  c++  java
  • 《算法》第四章部分程序 part 12

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图

    ● 无向符号图

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.In;
     4 import edu.princeton.cs.algs4.StdIn;
     5 import edu.princeton.cs.algs4.StdOut;
     6 import edu.princeton.cs.algs4.Graph;
     7 import edu.princeton.cs.algs4.ST;
     8 
     9 public class class01
    10 {
    11     private ST<String, Integer> st;  // 字符串转索引
    12     private String[] keys;           // 索引转字符串
    13     private Graph graph;
    14 
    15     public class01(String filename, String delimiter)
    16     {
    17         st = new ST<String, Integer>();
    18         for (In in = new In(filename); !in.isEmpty();)      // 收集符号,存入集合,编号
    19         {
    20             String[] a = in.readLine().split(delimiter);
    21             for (int i = 0; i < a.length; i++)
    22             {
    23                 if (!st.contains(a[i]))
    24                     st.put(a[i], st.size());
    25             }
    26         }
    27         keys = new String[st.size()];
    28         for (String name : st.keys())
    29             keys[st.get(name)] = name;
    30         graph = new Graph(st.size());
    31         for (In in = new In(filename); in.hasNextLine();)   // 再读一次,建图
    32         {
    33             String[] a = in.readLine().split(delimiter);
    34             int v = st.get(a[0]);
    35             for (int i = 1; i < a.length; i++)
    36             {
    37                 int w = st.get(a[i]);
    38                 graph.addEdge(v, w);
    39             }
    40         }
    41     }
    42 
    43     public boolean contains(String s)
    44     {
    45         return st.contains(s);
    46     }
    47 
    48     public int indexOf(String s)
    49     {
    50         return st.get(s);
    51     }
    52 
    53     public String nameOf(int v)
    54     {
    55         return keys[v];
    56     }
    57 
    58     public Graph graph()
    59     {
    60         return graph;
    61     }
    62 
    63     public static void main(String[] args)
    64     {
    65         String filename = args[0];             // 输入符号图(邻接表)的文件名和分隔符
    66         String delimiter = args[1];
    67         class01 sg = new class01(filename, delimiter);
    68         for (Graph graph = sg.graph(); StdIn.hasNextLine();)
    69         {
    70             String source = StdIn.readLine();   // 再输入需要查询的顶点
    71             if (sg.contains(source))
    72             {
    73                 int s = sg.indexOf(source);
    74                 for (int v : graph.adj(s))
    75                     StdOut.println("   " + sg.nameOf(v));
    76             }
    77             else
    78                 StdOut.println("input not contain '" + source + "'");
    79         }
    80     }
    81 }

    ● 有向符号图,与无向情形仅有方法名不同

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.In;
     4 import edu.princeton.cs.algs4.StdIn;
     5 import edu.princeton.cs.algs4.StdOut;
     6 import edu.princeton.cs.algs4.Digraph;
     7 import edu.princeton.cs.algs4.ST;
     8 
     9 public class class01
    10 {
    11     private ST<String, Integer> st;  
    12     private String[] keys;           
    13     private Digraph graph;           
    14 
    15     public class01(String filename, String delimiter)
    16     {
    17         st = new ST<String, Integer>();    
    18         for (In in = new In(filename); !in.isEmpty();)
    19         {
    20             String[] a = in.readLine().split(delimiter);
    21             for (int i = 0; i < a.length; i++) 
    22             {
    23                 if (!st.contains(a[i]))
    24                     st.put(a[i], st.size());
    25             }
    26         }        
    27         keys = new String[st.size()];
    28         for (String name : st.keys())
    29             keys[st.get(name)] = name;        
    30         graph = new Graph(st.size());
    31         for (In in = new In(filename); in.hasNextLine();)   // 再读一次,建图
    32         {
    33             String[] a = in.readLine().split(delimiter);
    34             int v = st.get(a[0]);
    35             for (int i = 1; i < a.length; i++) 
    36             {
    37                 int w = st.get(a[i]);
    38                 graph.addEdge(v, w);
    39             }
    40         }
    41     }
    42 
    43     public boolean contains(String s)
    44     {
    45         return st.contains(s);
    46     }
    47 
    48     public int indexOf(String s)
    49     {
    50         return st.get(s);
    51     }
    52          
    53     public String nameOf(int v)
    54     {    
    55         return keys[v];
    56     }
    57 
    58     public Digraph digraph()
    59     {
    60         return graph;
    61     }
    62     
    63     public static void main(String[] args)
    64     {
    65         String filename = args[0];
    66         String delimiter = args[1];
    67         class01 sg = new class01(filename, delimiter);        
    68         for (Digraph graph = sg.digraph(); StdIn.hasNextLine();)
    69         {
    70             String t = StdIn.readLine();
    71             for (int v : graph.adj(sg.indexOf(t)))
    72                 StdOut.println("   " + sg.nameOf(v));
    73         }
    74     }
    75 }

    ● 有权边结构

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.StdOut;
     4 import edu.princeton.cs.algs4.Edge;
     5 
     6 public class class01 implements Comparable<Edge>
     7 {
     8     private final int v;
     9     private final int w;
    10     private final double weight;
    11 
    12     public class01(int inputV, int inputW, double inputWeight)
    13     {
    14         if (inputV < 0 || inputW < 0 || Double.isNaN(inputWeight))
    15             throw new IllegalArgumentException("
    <Construtor> v < 0 || w < 0 || weight == NaN.
    ");
    16         v = inputV;
    17         w = inputW;
    18         weight = inputWeight;
    19     }
    20 
    21     public double weight()
    22     {
    23         return weight;
    24     }
    25 
    26     public int either()
    27     {
    28         return v;
    29     }
    30 
    31     public int other(int vertex)
    32     {
    33         if (vertex == v)
    34             return w;
    35         if (vertex == w)
    36             return v;
    37         throw new IllegalArgumentException("
    <other> No such point.
    ");
    38     }
    39 
    40     @Override
    41         public int compareTo(class01 that)
    42     {
    43         return Double.compare(weight, that.weight);
    44     }
    45 
    46     public String toString()
    47     {
    48         return String.format("%d-%d %.5f", v, w, weight);
    49     }
    50 
    51     public static void main(String[] args)
    52     {
    53         class01 e = new class01(12, 34, 5.67);
    54         StdOut.println(e);
    55     }
    56 }

    ● 有边权有向图

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.In;
      4 import edu.princeton.cs.algs4.StdOut;
      5 import edu.princeton.cs.algs4.StdRandom;
      6 import edu.princeton.cs.algs4.Bag;
      7 import edu.princeton.cs.algs4.Stack;
      8 import edu.princeton.cs.algs4.Edge;
      9 
     10 public class class01
     11 {
     12     private static final String NEWLINE = System.getProperty("line.separator");// 换行,按操作系统适配
     13 
     14     private final int V;
     15     private int E;
     16     private Bag<Edge>[] adj;
     17 
     18     public class01(int inputV)
     19     {
     20         if (inputV < 0)
     21             throw new IllegalArgumentException("
    <Constructor> V < 0.
    ");
     22         V = inputV;
     23         E = 0;
     24         adj = (Bag<Edge>[]) new Bag[V];
     25         for (int v = 0; v < V; v++)
     26             adj[v] = new Bag<Edge>();
     27     }
     28 
     29     public class01(int inputV, int inputE)
     30     {
     31         this(inputV);
     32         if (inputE < 0)
     33             throw new IllegalArgumentException("
    <Constructor> E < 0.
    ");
     34         for (int i = 0; i < E; i++)                 // 添加 E 条边,随机权重
     35         {
     36             int v = StdRandom.uniform(V);
     37             int w = StdRandom.uniform(V);
     38             Edge e = new Edge(v, w, Math.round(100 * StdRandom.uniform()) / 100.0);
     39             addEdge(e);
     40         }
     41     }
     42 
     43     public class01(In in)
     44     {
     45         this(in.readInt());
     46         E = in.readInt();
     47         if (E < 0)
     48             throw new IllegalArgumentException("
    <Constructor> E < 0.
    ");
     49         for (int i = 0; i < E; i++)
     50         {
     51             int v = in.readInt();
     52             int w = in.readInt();
     53             Edge e = new Edge(v, w, in.readDouble());
     54             addEdge(e);
     55         }
     56     }
     57 
     58     public class01(class01 G)
     59     {
     60         this(G.V());
     61         E = G.E();
     62         for (int v = 0; v < G.V(); v++)
     63         {
     64             Stack<Edge> reverse = new Stack<Edge>();// 用栈保存原图遍历得到的边,吐栈是回复顺序
     65             for (Edge e : G.adj[v])
     66                 reverse.push(e);
     67             for (Edge e : reverse)
     68                 adj[v].add(e);
     69         }
     70     }
     71 
     72     public int V()
     73     {
     74         return V;
     75     }
     76 
     77     public int E()
     78     {
     79         return E;
     80     }
     81 
     82     public void addEdge(Edge e)
     83     {
     84         int v = e.either();
     85         int w = e.other(v);
     86         adj[v].add(e);
     87         adj[w].add(e);
     88         E++;
     89     }
     90 
     91     public Iterable<Edge> adj(int v)
     92     {
     93         return adj[v];
     94     }
     95 
     96     public int degree(int v)
     97     {
     98         return adj[v].size();
     99     }
    100 
    101     public Iterable<Edge> edges()
    102     {
    103         Bag<Edge> list = new Bag<Edge>();
    104         for (int v = 0; v < V; v++)
    105         {
    106             boolean selfLoop = false;   // 注意两条自边只算一个自环
    107             for (Edge e : adj(v))
    108             {
    109                 if (e.other(v) == v)
    110                 {
    111                     if (!selfLoop)
    112                         list.add(e);
    113                     selfLoop = !selfLoop;
    114                 }
    115                 if (e.other(v) > v)     // 索引控制,防止反复添加同一条边
    116                     list.add(e);
    117             }
    118         }
    119         return list;
    120     }
    121 
    122     public String toString()
    123     {
    124         StringBuilder s = new StringBuilder();
    125         s.append(V + " " + E + NEWLINE);
    126         for (int v = 0; v < V; v++)
    127         {
    128             s.append(v + ": ");
    129             for (Edge e : adj[v])
    130                 s.append(e + "  ");
    131             s.append(NEWLINE);
    132         }
    133         return s.toString();
    134     }
    135 
    136     public static void main(String[] args)
    137     {
    138         In in = new In(args[0]);
    139         class01 G = new class01(in);
    140         StdOut.println(G);
    141     }
    142 }
  • 相关阅读:
    面试题库
    集合的交、查、并
    mysql_server安装
    maven构建jar包
    Centos7下 升级php5.4到7.1 yum安装
    redis
    常见shell用法
    Mac下的LDAP客户端 ApacheDirectoryStudio
    redis弱密码漏洞利用
    Freeradius+Cisco2500AC+OpenLdap认证
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9830097.html
Copyright © 2011-2022 走看看