▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法

● 拓扑排序 1

 package package01;

 import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.SymbolDigraph;
import edu.princeton.cs.algs4.DirectedCycle;
import edu.princeton.cs.algs4.DepthFirstOrder;
import edu.princeton.cs.algs4.EdgeWeightedDigraph;
import edu.princeton.cs.algs4.EdgeWeightedDirectedCycle; public class class01
{
private Iterable<Integer> order; // 拓扑排序的结果
private int[] rank; // 顶点 v 在拓扑排序中的序号为 rank[v] public class01(Digraph G) // 从有向图生成拓扑排序
{
DirectedCycle finder = new DirectedCycle(G); // 存在环则不能排序
if (!finder.hasCycle())
{
DepthFirstOrder dfs = new DepthFirstOrder(G); // 做 G 的深度优先搜索
order = dfs.reversePost(); // 取逆后序依次标号
rank = new int[G.V()];
int i = 0;
for (int v : order)
rank[v] = i++;
}
} public class01(EdgeWeightedDigraph G) // 从加权边有向图生成拓扑排序(算法一样,只是数据结构不同)
{
EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);
if (!finder.hasCycle())
{
DepthFirstOrder dfs = new DepthFirstOrder(G);
order = dfs.reversePost();
rank = new int[G.V()];
int i = 0;
for (int v : order)
rank[v] = i++;
}
} public Iterable<Integer> order()
{
return order;
} public boolean hasOrder()
{
return order != null;
} public int rank(int v)
{
return hasOrder() ? rank[v] : -1;
} public static void main(String[] args)
{
String filename = args[0];
String delimiter = args[1]; // 分隔符
SymbolDigraph sg = new SymbolDigraph(filename, delimiter);
class01 topological = new class01(sg.digraph());
for (int v : topological.order())
System.out.println(sg.nameOf(v));
}
}

● 拓扑排序 2

 package package01;

 import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.DigraphGenerator;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.EdgeWeightedDigraph; public class class01
{
private Queue<Integer> order;
private int[] rank; public class01(Digraph G)
{
order = new Queue<Integer>();
rank = new int[G.V()];
int[] indegree = new int[G.V()];
for (int v = 0; v < G.V(); v++)
indegree[v] = G.indegree(v);
int count = 0;
Queue<Integer> queue = new Queue<Integer>();
for (int v = 0; v < G.V(); v++) // 收集所有没有前提条件的顶点
{
if (indegree[v] == 0)
queue.enqueue(v);
}
for (; !queue.isEmpty();)
{
int v = queue.dequeue();
order.enqueue(v); // 事件 v 完成,将其放入输出队列, 并给一个序号
rank[v] = count++;
for (int w : G.adj(v)) // 所有紧接着 v 的事件的前提条件减少 1
{
indegree[w]--;
if (indegree[w] == 0) // 收集此时没有前提条件的事件
queue.enqueue(w);
}
}
if (count != G.V()) // 遍历结束,还有顶点有入度,说明存在环
order = null;
} public class01(EdgeWeightedDigraph G)
{
order = new Queue<Integer>();
rank = new int[G.V()];
int[] indegree = new int[G.V()];
for (int v = 0; v < G.V(); v++)
indegree[v] = G.indegree(v);
int count = 0;
Queue<Integer> queue = new Queue<Integer>();
for (int v = 0; v < G.V(); v++)
{
if (indegree[v] == 0)
queue.enqueue(v);
}
for (; !queue.isEmpty();)
{
int v = queue.dequeue();
order.enqueue(v);
rank[v] = count++;
for (DirectedEdge e : G.adj(v))
{
int w = e.to();
indegree[w]--;
if (indegree[w] == 0)
queue.enqueue(w);
}
}
if (count != G.V())
order = null;
} public Iterable<Integer> order()
{
return order;
} public boolean hasOrder()
{
return order != null;
} public int rank(int v)
{
return hasOrder() ? rank[v] : -1;
} public static void main(String[] args)
{
int V = Integer.parseInt(args[0]); // 生成DAG G(V,E),再添加 F 条边
int E = Integer.parseInt(args[1]);
int F = Integer.parseInt(args[2]);
Digraph G1 = DigraphGenerator.dag(V, E); // G1 是无边圈的
EdgeWeightedDigraph G2 = new EdgeWeightedDigraph(V);// G2 有边权的
for (int v = 0; v < G1.V(); v++)
{
for (int w : G1.adj(v))
G2.addEdge(new DirectedEdge(v, w, 0.0));
}
for (int i = 0; i < F; i++)
{
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
G1.addEdge(v, w);
G2.addEdge(new DirectedEdge(v, w, 0.0));
}
StdOut.println(G1);
StdOut.println();
StdOut.println(G2);
class01 topological1 = new class01(G1); // 分别计算 G1 和 G2 的
if (!topological1.hasOrder())
StdOut.println("Not a DAG");
else
{
StdOut.print("Topological order: ");
for (int v : topological1.order())
StdOut.print(v + " ");
StdOut.println();
}
class01 topological2 = new class01(G2);
if (!topological2.hasOrder())
StdOut.println("Not a DAG");
else
{
StdOut.print("Topological order: ");
for (int v : topological2.order())
StdOut.print(v + " ");
StdOut.println();
}
}
}

《算法》第四章部分程序 part 9的更多相关文章

  1. 《算法》第四章部分程序 part 19

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...

  2. 《算法》第四章部分程序 part 18

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...

  3. 《算法》第四章部分程序 part 16

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径 ● Dijkstra 算法求有向图最短路径 package packa ...

  4. 《算法》第四章部分程序 part 15

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...

  5. 《算法》第四章部分程序 part 14

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...

  6. 《算法》第四章部分程序 part 10

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...

  7. 《算法》第四章部分程序 part 17

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...

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

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

  9. 《算法》第四章部分程序 part 12

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

随机推荐

  1. 找进程的窗口Handle

    Process[] ProcessList = Process.GetProcessesByName("mspaint");//画图板 IntPtr test = ProcessL ...

  2. WPF Demo13 GridSplitter

    <Window x:Class="Commands.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...

  3. phoenix初步

    更新系统包管理工具hex mix local.hex 安装phoenix,phoenix是elixir的web框架 mix archive.install https://github.com/pho ...

  4. Dubbo的原理以及详细原理、配置

    Dubbo的背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. Dubbo的应用 用于大规模 ...

  5. Ubuntu 14.10 下连接SuperVessel Cloud

    第一次创建实例后,系统会分配一个VPN用户,用于连接到系统. 官方帮助文档给出了使用方法 Linux VPN 客户端的配置方法 . 安装 VPNC: $ apt-get install vpnc $ ...

  6. 写在vue总结之前(一)

    在大概2016年6月吧,知道了vue,博客园有个博主用vue写了一个不算完整的博客园app,做出来的效果相比博客园原本的app看上去要华丽很多,那时候做前端还没多久,很多东西都不知道,别人说用vue开 ...

  7. [Easyui - Grid]为easyui的datagrid、treegrid增加表头菜单,用于显示或隐藏列

    为easyui的datagrid.treegrid增加表头菜单,用于显示或隐藏列 /** * @author 孙宇 * * @requires jQuery,EasyUI * * 为datagrid. ...

  8. P1033自由落体

    传送 杯具wa,惨痛的教训————别写一些情况多到要打表的判断,写着写着就wa了 这个题,我主要死在判断上了 第一遍20分的思路:看小车此时跨越几个整数点.因为我求出了此时小车的车头坐标和车尾坐标.然 ...

  9. 开发框架-Web-Java:JeePlus

    ylbtech-开发框架-Web-Java:JeePlus 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 0. http://www.jeeplus.org/ ...

  10. 云中树莓派(5):利用 AWS IoT Greengrass 进行 IoT 边缘计算

    云中树莓派(1):环境准备 云中树莓派(2):将传感器数据上传到AWS IoT 并利用Kibana进行展示 云中树莓派(3):通过 AWS IoT 控制树莓派上的Led 云中树莓派(4):利用声音传感 ...