《算法》第四章部分程序 part 13
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序、后序和逆后续遍历,以及传递闭包
● 图的前序、后序和逆后续遍历
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.EdgeWeightedDigraph;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.Stack; public class class01
{
private boolean[] marked;
private int[] pre; // 前序顶点列表(索引 -> 顶点)
private int[] post; // 后序顶点列表
private Queue<Integer> preorder; // 前序队列(顶点)
private Queue<Integer> postorder; // 后续队列
private int preCounter; // 前序计数器
private int postCounter; // 后序计数器 public class01(Digraph G)
{
pre = new int[G.V()];
post = new int[G.V()];
postorder = new Queue<Integer>();
preorder = new Queue<Integer>();
marked = new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
{
if (!marked[v])
dfs(G, v);
}
} public class01(EdgeWeightedDigraph G)
{
pre = new int[G.V()];
post = new int[G.V()];
postorder = new Queue<Integer>();
preorder = new Queue<Integer>();
marked = new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
{
if (!marked[v])
dfs(G, v);
}
} private void dfs(Digraph G, int v)
{
marked[v] = true;
pre[v] = preCounter++; // 前序和后序差别在于,将当前顶点加入队列以及递归的先后顺序
preorder.enqueue(v);
for (int w : G.adj(v))
{
if (!marked[w])
dfs(G, w);
}
postorder.enqueue(v);
post[v] = postCounter++;
} private void dfs(EdgeWeightedDigraph G, int v)
{
marked[v] = true;
pre[v] = preCounter++;
preorder.enqueue(v);
for (DirectedEdge e : G.adj(v))
{
int w = e.to();
if (!marked[w])
dfs(G, w);
}
postorder.enqueue(v);
post[v] = postCounter++;
} public int pre(int v)
{
return pre[v];
} public int post(int v)
{
return post[v];
} public Iterable<Integer> pre()
{
return preorder;
} public Iterable<Integer> post()
{
return postorder;
} public Iterable<Integer> reversePost() // 用后续队列生成逆后序栈
{
Stack<Integer> reverse = new Stack<Integer>();
for (int v : postorder)
reverse.push(v);
return reverse;
} public static void main(String[] args)
{
In in = new In(args[0]);
Digraph G = new Digraph(in);
class01 dfs = new class01(G);
StdOut.println(" v pre post");
StdOut.println("--------------");
for (int v = 0; v < G.V(); v++)
StdOut.printf("%4d %4d %4d\n", v, dfs.pre(v), dfs.post(v)); StdOut.print("Preorder: "); // 分别输出前序、后序和逆后序
for (int v : dfs.pre())
StdOut.print(v + " ");
StdOut.println(); StdOut.print("Postorder: ");
for (int v : dfs.post())
StdOut.print(v + " ");
StdOut.println(); StdOut.print("Reverse postorder: ");
for (int v : dfs.reversePost())
StdOut.print(v + " ");
StdOut.println();
}
}
● 传递闭包
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.DirectedDFS; public class class01
{
private DirectedDFS[] tc; public class01(Digraph G)
{
tc = new DirectedDFS[G.V()];
for (int v = 0; v < G.V(); v++) // 循环尝试从所有点开始深度优先遍历整个图,返回可达点的迭代器
tc[v] = new DirectedDFS(G, v);
} public boolean reachable(int v, int w)
{
return tc[v].marked(w);
} public static void main(String[] args)
{
In in = new In(args[0]);
Digraph G = new Digraph(in);
class01 tc = new class01(G); StdOut.print(" ");
for (int v = 0; v < G.V(); v++)
StdOut.printf("%3d", v);
StdOut.println("\n--------------------------------------------"); for (int v = 0; v < G.V(); v++)
{
StdOut.printf("%3d: ", v);
for (int w = 0; w < G.V(); w++)
StdOut.printf(tc.reachable(v, w) ? " T" : " ");
StdOut.println();
}
}
}
《算法》第四章部分程序 part 13的更多相关文章
- 《算法》第四章部分程序 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 12
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...
随机推荐
- delphi内存映射 与 映射数据获取
一.原理 通过使用“内存映射文件”,实现内存共享 二.主要操作 共享内存结构: PShareMem = ^TShareMem; TShareMem = Record id:stri ...
- 廖雪峰Java5集合-2List-2编写equals方法
List是一种有序链表: List内部按照放入元素的先后顺序存放 每个元素都可以通过索引确定自己的位置 boolean contains(Object o) 是否包含某个元素 int indexOf( ...
- 廖雪峰Java4反射与泛型-3范型-3编写泛型
编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...
- 廖雪峰Java2面向对象编程-3继承和多态-1继承
1.继承 继承是一种代码复用的方式. Student与Person有相同部分的代码. Student可以从Person继承,这样Student获得了Person的所有功能,只需要编写新增的功能即可.通 ...
- go中defer的理解--defer、return、返回值之间执行顺序
defer可以读取有名返回值 func c() (i int) { defer func() { i++ }() return 1 } 输出结果是2. 在开头的时候,我们知道defer是在return ...
- Dom操作的常用案例实现
本文介绍几个Dom操作的几个常用的案例.虽然现在各种web框架层出不穷,也很方便.但是了解最基本的实现方法对我们开发还是有很大的帮助的: 1.图片滚动案例 1.1 效果如下: 1.2 代码如下: ...
- PostgreSQL 之 yum安装 postgis 插件
版本说明: CentOS7.5 + PostgreSQL 10.5 参考资源: https://www.postgresql.org/download/linux/redhat/ http://dow ...
- 第6章 静态路由和动态路由(4)_OSPF动态路由协议
6. OSPF动态路由协议 6.1 OSPF协议(Open Shortest Path First,OSPF开放式最短路径优先协议) (1)通过路由器之间通告链路的状态来建立链路状态数据库,网络中所有 ...
- Hook技术之API拦截(API Hook)
一.实现过程 1.钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统. 2.在消息没有到达目的窗口前,钩子就捕获消息(即钩子函数先得到控制权). 3.钩子可以加工处理该消息,即钩子机制允许应 ...
- gulp 编译es6 react 教程 案例 配置
1.gulp基本配置: var gulp = require('gulp'), watch = require('gulp-watch'), babel = require('gulp-babel') ...