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

● 拓扑排序 1

  1. package package01;
  2.  
  3. import edu.princeton.cs.algs4.Digraph;
  4. import edu.princeton.cs.algs4.SymbolDigraph;
  5. import edu.princeton.cs.algs4.DirectedCycle;
  6. import edu.princeton.cs.algs4.DepthFirstOrder;
  7. import edu.princeton.cs.algs4.EdgeWeightedDigraph;
  8. import edu.princeton.cs.algs4.EdgeWeightedDirectedCycle;
  9.  
  10. public class class01
  11. {
  12. private Iterable<Integer> order; // 拓扑排序的结果
  13. private int[] rank; // 顶点 v 在拓扑排序中的序号为 rank[v]
  14.  
  15. public class01(Digraph G) // 从有向图生成拓扑排序
  16. {
  17. DirectedCycle finder = new DirectedCycle(G); // 存在环则不能排序
  18. if (!finder.hasCycle())
  19. {
  20. DepthFirstOrder dfs = new DepthFirstOrder(G); // 做 G 的深度优先搜索
  21. order = dfs.reversePost(); // 取逆后序依次标号
  22. rank = new int[G.V()];
  23. int i = 0;
  24. for (int v : order)
  25. rank[v] = i++;
  26. }
  27. }
  28.  
  29. public class01(EdgeWeightedDigraph G) // 从加权边有向图生成拓扑排序(算法一样,只是数据结构不同)
  30. {
  31. EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);
  32. if (!finder.hasCycle())
  33. {
  34. DepthFirstOrder dfs = new DepthFirstOrder(G);
  35. order = dfs.reversePost();
  36. rank = new int[G.V()];
  37. int i = 0;
  38. for (int v : order)
  39. rank[v] = i++;
  40. }
  41. }
  42.  
  43. public Iterable<Integer> order()
  44. {
  45. return order;
  46. }
  47.  
  48. public boolean hasOrder()
  49. {
  50. return order != null;
  51. }
  52.  
  53. public int rank(int v)
  54. {
  55. return hasOrder() ? rank[v] : -1;
  56. }
  57.  
  58. public static void main(String[] args)
  59. {
  60. String filename = args[0];
  61. String delimiter = args[1]; // 分隔符
  62. SymbolDigraph sg = new SymbolDigraph(filename, delimiter);
  63. class01 topological = new class01(sg.digraph());
  64. for (int v : topological.order())
  65. System.out.println(sg.nameOf(v));
  66. }
  67. }

● 拓扑排序 2

  1. package package01;
  2.  
  3. import edu.princeton.cs.algs4.StdOut;
  4. import edu.princeton.cs.algs4.StdRandom;
  5. import edu.princeton.cs.algs4.DigraphGenerator;
  6. import edu.princeton.cs.algs4.Digraph;
  7. import edu.princeton.cs.algs4.Queue;
  8. import edu.princeton.cs.algs4.DirectedEdge;
  9. import edu.princeton.cs.algs4.EdgeWeightedDigraph;
  10.  
  11. public class class01
  12. {
  13. private Queue<Integer> order;
  14. private int[] rank;
  15.  
  16. public class01(Digraph G)
  17. {
  18. order = new Queue<Integer>();
  19. rank = new int[G.V()];
  20. int[] indegree = new int[G.V()];
  21. for (int v = 0; v < G.V(); v++)
  22. indegree[v] = G.indegree(v);
  23. int count = 0;
  24. Queue<Integer> queue = new Queue<Integer>();
  25. for (int v = 0; v < G.V(); v++) // 收集所有没有前提条件的顶点
  26. {
  27. if (indegree[v] == 0)
  28. queue.enqueue(v);
  29. }
  30. for (; !queue.isEmpty();)
  31. {
  32. int v = queue.dequeue();
  33. order.enqueue(v); // 事件 v 完成,将其放入输出队列, 并给一个序号
  34. rank[v] = count++;
  35. for (int w : G.adj(v)) // 所有紧接着 v 的事件的前提条件减少 1
  36. {
  37. indegree[w]--;
  38. if (indegree[w] == 0) // 收集此时没有前提条件的事件
  39. queue.enqueue(w);
  40. }
  41. }
  42. if (count != G.V()) // 遍历结束,还有顶点有入度,说明存在环
  43. order = null;
  44. }
  45.  
  46. public class01(EdgeWeightedDigraph G)
  47. {
  48. order = new Queue<Integer>();
  49. rank = new int[G.V()];
  50. int[] indegree = new int[G.V()];
  51. for (int v = 0; v < G.V(); v++)
  52. indegree[v] = G.indegree(v);
  53. int count = 0;
  54. Queue<Integer> queue = new Queue<Integer>();
  55. for (int v = 0; v < G.V(); v++)
  56. {
  57. if (indegree[v] == 0)
  58. queue.enqueue(v);
  59. }
  60. for (; !queue.isEmpty();)
  61. {
  62. int v = queue.dequeue();
  63. order.enqueue(v);
  64. rank[v] = count++;
  65. for (DirectedEdge e : G.adj(v))
  66. {
  67. int w = e.to();
  68. indegree[w]--;
  69. if (indegree[w] == 0)
  70. queue.enqueue(w);
  71. }
  72. }
  73. if (count != G.V())
  74. order = null;
  75. }
  76.  
  77. public Iterable<Integer> order()
  78. {
  79. return order;
  80. }
  81.  
  82. public boolean hasOrder()
  83. {
  84. return order != null;
  85. }
  86.  
  87. public int rank(int v)
  88. {
  89. return hasOrder() ? rank[v] : -1;
  90. }
  91.  
  92. public static void main(String[] args)
  93. {
  94. int V = Integer.parseInt(args[0]); // 生成DAG G(V,E),再添加 F 条边
  95. int E = Integer.parseInt(args[1]);
  96. int F = Integer.parseInt(args[2]);
  97. Digraph G1 = DigraphGenerator.dag(V, E); // G1 是无边圈的
  98. EdgeWeightedDigraph G2 = new EdgeWeightedDigraph(V);// G2 有边权的
  99. for (int v = 0; v < G1.V(); v++)
  100. {
  101. for (int w : G1.adj(v))
  102. G2.addEdge(new DirectedEdge(v, w, 0.0));
  103. }
  104. for (int i = 0; i < F; i++)
  105. {
  106. int v = StdRandom.uniform(V);
  107. int w = StdRandom.uniform(V);
  108. G1.addEdge(v, w);
  109. G2.addEdge(new DirectedEdge(v, w, 0.0));
  110. }
  111. StdOut.println(G1);
  112. StdOut.println();
  113. StdOut.println(G2);
  114. class01 topological1 = new class01(G1); // 分别计算 G1 和 G2 的
  115. if (!topological1.hasOrder())
  116. StdOut.println("Not a DAG");
  117. else
  118. {
  119. StdOut.print("Topological order: ");
  120. for (int v : topological1.order())
  121. StdOut.print(v + " ");
  122. StdOut.println();
  123. }
  124. class01 topological2 = new class01(G2);
  125. if (!topological2.hasOrder())
  126. StdOut.println("Not a DAG");
  127. else
  128. {
  129. StdOut.print("Topological order: ");
  130. for (int v : topological2.order())
  131. StdOut.print(v + " ");
  132. StdOut.println();
  133. }
  134. }
  135. }

《算法》第四章部分程序 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. OpenTSDB安装

    时序数据库 时序数据库全称为时间序列数据库.主要用于处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据.时间序列数据主要由电力行业.化工行业.物联网行业等各类 ...

  2. 蓝桥杯-四阶幻方(DFS)

    标题:四阶幻方 把1~16的数字填入4x4的方格中,使得行.列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方. 四阶幻方可能有很多方案.如果固定左上角为1,请计算一共有多少种方案. 比如: ...

  3. 【springBoot】之配置文件application

    springboot使用一个全局的配置文件application.properties或者是application.yml,放在在src/main/recesources下或者在类路径下的/confi ...

  4. C/C++中字符串和数字互转小结

    一. 数字 转 char*型 1.sprintf函数(适合C和C++) 示例: char str[50]; int num = 345; sprintf(str,"%d",num) ...

  5. python 引用计数

    转载:NeilLee(有修改)   一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为 ...

  6. ubuntu16.04 彻底卸载MySQL

    以MySQL- 5.7.18为例: sudo apt-get autoremove --purge mysql-server-5.7 #sudo apt-get remove mysql-server ...

  7. PAT 乙级 1046 划拳(15) C++版

    1046. 划拳(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 划拳是古老中国酒文化的一个有趣的组成部分 ...

  8. Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用-um

    ylbtech-Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用 1.返回顶部 1. Java 实例 - Enum(枚举)构造函数及方法的 ...

  9. Jmeter(二十五)Jmeter之系统函数

    都忘了Jmeter4.0已发布((*^▽^*))具体优化项还没体验,记录一下,传送门:http://jmeter.apache.org/download_jmeter.cgi Jmeter的系统函数已 ...

  10. java中synchronized 用在实例方法和对象方法上面的区别

    https://bijian1013.iteye.com/blog/1836575 在Java中,synchronized 是用来表示同步的,我们可以synchronized 来修饰一个方法.也可以s ...