《算法》第四章部分程序 part 12
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图
● 无向符号图
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.ST; public class class01
{
private ST<String, Integer> st; // 字符串转索引
private String[] keys; // 索引转字符串
private Graph graph; public class01(String filename, String delimiter)
{
st = new ST<String, Integer>();
for (In in = new In(filename); !in.isEmpty();) // 收集符号,存入集合,编号
{
String[] a = in.readLine().split(delimiter);
for (int i = 0; i < a.length; i++)
{
if (!st.contains(a[i]))
st.put(a[i], st.size());
}
}
keys = new String[st.size()];
for (String name : st.keys())
keys[st.get(name)] = name;
graph = new Graph(st.size());
for (In in = new In(filename); in.hasNextLine();) // 再读一次,建图
{
String[] a = in.readLine().split(delimiter);
int v = st.get(a[0]);
for (int i = 1; i < a.length; i++)
{
int w = st.get(a[i]);
graph.addEdge(v, w);
}
}
} public boolean contains(String s)
{
return st.contains(s);
} public int indexOf(String s)
{
return st.get(s);
} public String nameOf(int v)
{
return keys[v];
} public Graph graph()
{
return graph;
} public static void main(String[] args)
{
String filename = args[0]; // 输入符号图(邻接表)的文件名和分隔符
String delimiter = args[1];
class01 sg = new class01(filename, delimiter);
for (Graph graph = sg.graph(); StdIn.hasNextLine();)
{
String source = StdIn.readLine(); // 再输入需要查询的顶点
if (sg.contains(source))
{
int s = sg.indexOf(source);
for (int v : graph.adj(s))
StdOut.println(" " + sg.nameOf(v));
}
else
StdOut.println("input not contain '" + source + "'");
}
}
}
● 有向符号图,与无向情形仅有方法名不同
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.ST; public class class01
{
private ST<String, Integer> st;
private String[] keys;
private Digraph graph; public class01(String filename, String delimiter)
{
st = new ST<String, Integer>();
for (In in = new In(filename); !in.isEmpty();)
{
String[] a = in.readLine().split(delimiter);
for (int i = 0; i < a.length; i++)
{
if (!st.contains(a[i]))
st.put(a[i], st.size());
}
}
keys = new String[st.size()];
for (String name : st.keys())
keys[st.get(name)] = name;
graph = new Graph(st.size());
for (In in = new In(filename); in.hasNextLine();) // 再读一次,建图
{
String[] a = in.readLine().split(delimiter);
int v = st.get(a[0]);
for (int i = 1; i < a.length; i++)
{
int w = st.get(a[i]);
graph.addEdge(v, w);
}
}
} public boolean contains(String s)
{
return st.contains(s);
} public int indexOf(String s)
{
return st.get(s);
} public String nameOf(int v)
{
return keys[v];
} public Digraph digraph()
{
return graph;
} public static void main(String[] args)
{
String filename = args[0];
String delimiter = args[1];
class01 sg = new class01(filename, delimiter);
for (Digraph graph = sg.digraph(); StdIn.hasNextLine();)
{
String t = StdIn.readLine();
for (int v : graph.adj(sg.indexOf(t)))
StdOut.println(" " + sg.nameOf(v));
}
}
}
● 有权边结构
package package01; import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Edge; public class class01 implements Comparable<Edge>
{
private final int v;
private final int w;
private final double weight; public class01(int inputV, int inputW, double inputWeight)
{
if (inputV < 0 || inputW < 0 || Double.isNaN(inputWeight))
throw new IllegalArgumentException("\n<Construtor> v < 0 || w < 0 || weight == NaN.\n");
v = inputV;
w = inputW;
weight = inputWeight;
} public double weight()
{
return weight;
} public int either()
{
return v;
} public int other(int vertex)
{
if (vertex == v)
return w;
if (vertex == w)
return v;
throw new IllegalArgumentException("\n<other> No such point.\n");
} @Override
public int compareTo(class01 that)
{
return Double.compare(weight, that.weight);
} public String toString()
{
return String.format("%d-%d %.5f", v, w, weight);
} public static void main(String[] args)
{
class01 e = new class01(12, 34, 5.67);
StdOut.println(e);
}
}
● 有边权有向图
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Bag;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.Edge; public class class01
{
private static final String NEWLINE = System.getProperty("line.separator");// 换行,按操作系统适配 private final int V;
private int E;
private Bag<Edge>[] adj; public class01(int inputV)
{
if (inputV < 0)
throw new IllegalArgumentException("\n<Constructor> V < 0.\n");
V = inputV;
E = 0;
adj = (Bag<Edge>[]) new Bag[V];
for (int v = 0; v < V; v++)
adj[v] = new Bag<Edge>();
} public class01(int inputV, int inputE)
{
this(inputV);
if (inputE < 0)
throw new IllegalArgumentException("\n<Constructor> E < 0.\n");
for (int i = 0; i < E; i++) // 添加 E 条边,随机权重
{
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w, Math.round(100 * StdRandom.uniform()) / 100.0);
addEdge(e);
}
} public class01(In in)
{
this(in.readInt());
E = in.readInt();
if (E < 0)
throw new IllegalArgumentException("\n<Constructor> E < 0.\n");
for (int i = 0; i < E; i++)
{
int v = in.readInt();
int w = in.readInt();
Edge e = new Edge(v, w, in.readDouble());
addEdge(e);
}
} public class01(class01 G)
{
this(G.V());
E = G.E();
for (int v = 0; v < G.V(); v++)
{
Stack<Edge> reverse = new Stack<Edge>();// 用栈保存原图遍历得到的边,吐栈是回复顺序
for (Edge e : G.adj[v])
reverse.push(e);
for (Edge e : reverse)
adj[v].add(e);
}
} public int V()
{
return V;
} public int E()
{
return E;
} public void addEdge(Edge e)
{
int v = e.either();
int w = e.other(v);
adj[v].add(e);
adj[w].add(e);
E++;
} public Iterable<Edge> adj(int v)
{
return adj[v];
} public int degree(int v)
{
return adj[v].size();
} public Iterable<Edge> edges()
{
Bag<Edge> list = new Bag<Edge>();
for (int v = 0; v < V; v++)
{
boolean selfLoop = false; // 注意两条自边只算一个自环
for (Edge e : adj(v))
{
if (e.other(v) == v)
{
if (!selfLoop)
list.add(e);
selfLoop = !selfLoop;
}
if (e.other(v) > v) // 索引控制,防止反复添加同一条边
list.add(e);
}
}
return list;
} public String toString()
{
StringBuilder s = new StringBuilder();
s.append(V + " " + E + NEWLINE);
for (int v = 0; v < V; v++)
{
s.append(v + ": ");
for (Edge e : adj[v])
s.append(e + " ");
s.append(NEWLINE);
}
return s.toString();
} public static void main(String[] args)
{
In in = new In(args[0]);
class01 G = new class01(in);
StdOut.println(G);
}
}
《算法》第四章部分程序 part 12的更多相关文章
- 《算法》第四章部分程序 part 19
▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...
- 《算法》第四章部分程序 part 18
▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...
- 《算法》第四章部分程序 part 16
▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径 ● Dijkstra 算法求有向图最短路径 package packa ...
- 《算法》第四章部分程序 part 15
▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...
- 《算法》第四章部分程序 part 14
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...
- 《算法》第四章部分程序 part 10
▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...
- 《算法》第四章部分程序 part 9
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...
- 《算法》第四章部分程序 part 17
▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...
- 《算法》第四章部分程序 part 13
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...
随机推荐
- jenkins构建触发器详解-不登录触发远程构建
利用jenkins的远程构建功能,我们可以使用任何脚本,甚至定制一个Web页来控制Job的执行,但是远程构建你如果直接使用的话,老是需要登录才能执行,如何避免登录?稍微折腾了一下,调通了. 1.首先去 ...
- STL序列式容器学习总结
STL序列式容器学习总结 参考资料:<STL源码剖析> 参考网址: Vector: http://www.cnblogs.com/zhonghuasong/p/5975979.html L ...
- 详细记录sql运行时间(精确到毫秒)
写程序的人,往往需要分析所写的SQL语句是否已经优化过了,服务器的响应时间有多快,这个时候就需要用到SQL的STATISTICS状态值来查看了. 通过设置STATISTICS我们可以查看执行SQL时的 ...
- PAT 乙级 1068 万绿丛中一点红(20 分)
1068 万绿丛中一点红(20 分) 对于计算机而言,颜色不过是像素点对应的一个 24 位的数值.现给定一幅分辨率为 M×N 的画,要求你找出万绿丛中的一点红,即有独一无二颜色的那个像素点,并且该点的 ...
- 服务容错保护断路器Hystrix之四:断路器监控(Hystrix Dashboard)-turbine集群监控
turbine 英[ˈtɜ:baɪn] n. 汽轮机; 涡轮机; 透平机; OK,上文我们看了一个监控单体应用的例子,在实际应用中,我们要监控的应用往往是一个集群,这个时候我们就得采取Turbine集 ...
- [转][xml]SQL转义
SQL语句包含">"和"<"时,在PL/SQL中可以正常运行,但是放在XML中,编译报错,这是因为在XML文档中的所有文本都会被解析器解析,文本内容 ...
- grep简单用法
grep 常用参数: -c: 打印符合要求的行数 -i :忽略大小写 -n:输出行和行号 -v:打印不符合要求的行,即反选 -A:后跟数字(有无空格都可以),例如-A2 表示打印筛选行及前2行 -B: ...
- 跨域的案例 以百度接口/手写接口为例,还有jQuery写法
仅在js部分输入即可 百度接口的案例 <script> function fn(data){ console.log(data) } </script> <script ...
- Scrapy学习篇(一)之框架
概览 在具体的学习scrapy之前,我们先对scrapy的架构做一个简单的了解,之后所有的内容都是基于此架构实现的,在初学阶段只需要简单的了解即可,之后的学习中,你会对此架构有更深的理解.下面是scr ...
- [UE4]蓝图比C++慢10倍,是吗?
首先,蓝图肯定是比C++慢. 任何脚本语言(需要解释执行的语言),和C++相比可能达到十倍甚至百倍的差距.比如Java.Python.Lua,JS. 脚本语言是运行在虚拟机上的,所以它们比起直接运行的 ...