《算法》第四章部分程序 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 ...
随机推荐
- WIN10 网速问题,边下载 边逛论坛 电脑 有点卡
引用:https://www.chiphell.com/forum.php?mod=viewthread&tid=1961836&extra=page%3D1&mobile=2 ...
- Winfrom DataGridView中使用Tooltip
第一步:添加DataGridView.Tooltip控件,略 第二步:设置ToolTip 相关属性,略,参考下图 第三步:DataGridView 添加 CellMouseEnter.CellMous ...
- 【优化】自定义抛出throw 对象练习
package ltb6w; import java.util.*; public class Bank { private boolean bool=true; private String sel ...
- ALGO-120_蓝桥杯_算法训练_学做菜
问题描述 涛涛立志要做新好青年,他最近在学做菜.由于技术还很生疏,他只会用鸡蛋,西红柿,鸡丁,辣酱这四种原料来做菜,我们给这四种原料标上字母A,B,C,D. 涛涛现在会做的菜有五种: . 西红柿炒鸡蛋 ...
- react路由嵌套
所谓的嵌套路由就是在某些以及路由下面存在二级路由,这些二级路由除了公用一级路由导航模块外,还公用当前的二级路由的导航模块,也就是部分进行了切换,要实现嵌套路由,首先回顾之前的内容,实现基本的react ...
- [转] 关于 Ceph PG
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...
- is与==
is和==的区别 1. id() 通过id()我们可以查看到⼀一个变量表示的值在内存中的地址. a1 = 100 b1 = 100 print(id(a1),id(b1)) #14071247240 ...
- Linux mysql 5.7.23 主从复制(异步复制)
docker容器主节点: 172.17.0.9 docker容器子节点: 172.17.0.10 异步复制: 首先确认主库和从库是否一致,最好都是刚刚初始化的干净的数据库 如果主库正在使用不能初始化 ...
- 在Docker中安装配置Oracle11g并实现数据持久化
1.拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g 镜像详情:https://dev.aliyun.com/ ...
- java中原生的发送http请求(无任何的jar包导入)
package com.teamsun.pay.wxpay.util; import java.io.BufferedReader; import java.io.IOException; impor ...