计算流图中的前必经节点
2014-01-30 07:00
134 查看
《现代编译器的Java实现》中的一图,左边是流图,右边是必经节点树
根据必经节点的算法写了程序验证了下。
只是为了验证算法,并没有考虑最优算法,不过因为此流图足够简单,所以只迭代了两次即求出了结果。
代码如下:
Node类抽象图中的节点,Dominator类用来计算
import java.util.ArrayList; import java.util.List; public class Node { // 序号 public int no; // 后接节点列表 public List<Node> nextList = new ArrayList<Node>(); // 前接节点列表 public List<Node> preList = new ArrayList<Node>(); // 初始前必经节点(全体节点) public List<Node> dominatorList = new ArrayList<Node>(); public Node(int no) { this.no = no; } public void addNext(Node n){ nextList.add(n); n.preList.add(this); } public String toString(){ return no+""; } }
import java.util.ArrayList; import java.util.List; public class Dominator { public static void main(String[] args) { //初期化所有节点 并设置节点间连接关系 List<Node> nodeList = getNodeList(12); // 计算前必经节点 doDominator(nodeList); //打印必经节点列表 printResult(nodeList); } // 打印必经结果 public static void printResult(List<Node> nodeList) { for (int i = 0; i < nodeList.size(); i++) { Node node = nodeList.get(i); System.out.println("*******************"); System.out.println("node" + (i + 1)); printNodeListNo(node.dominatorList); } } //打印节点NO public static void printNodeListNo(List<Node> nodeList) { System.out.println("------"); for (int i = 0; i < nodeList.size(); i++) { if (i != 0) { System.out.print(","); } System.out.print(nodeList.get(i).no); } System.out.println(); } // 计算必经节点 public static void doDominator(List<Node> nodeList) { //迭代次数 int n = 1; //判断状态是否稳定Flag boolean changed = true; while (changed) { System.out.println("迭代次数:" + n++); changed = false; for (int i = 0; i < nodeList.size(); i++) { Node node = nodeList.get(i); List<Node> lastDominatorList = new ArrayList<Node>(); lastDominatorList.addAll(node.dominatorList); List<Node> temList = new ArrayList<Node>(); for (Node preNode : node.preList) { List<Node> preDomList = preNode.dominatorList; if (temList.isEmpty()) { temList.addAll(preDomList); } else { temList.retainAll(preDomList); } } temList.add(node); int lastSize = lastDominatorList.size(); lastDominatorList.retainAll(temList); if (lastSize != lastDominatorList.size()) { node.dominatorList = temList; changed = true; } } } } //初期化所有节点 并设置节点间连接关系 public static List<Node> getNodeList(int size) { List<Node> nodeList = new ArrayList<Node>(size); for (int i = 0; i < size; i++) { Node node = new Node(i + 1); nodeList.add(node); } Node node1 = nodeList.get(0); Node node2 = nodeList.get(1); Node node3 = nodeList.get(2); Node node4 = nodeList.get(3); Node node5 = nodeList.get(4); Node node6 = nodeList.get(5); Node node7 = nodeList.get(6); Node node8 = nodeList.get(7); Node node9 = nodeList.get(8); Node node10 = nodeList.get(9); Node node11 = nodeList.get(10); Node node12 = nodeList.get(11); // 节点之间关系设定 node1.addNext(node2); // node2.addNext(node3); node2.addNext(node4); // node3.addNext(node2); // node4.addNext(node2); node4.addNext(node5); node4.addNext(node6); // node5.addNext(node7); node5.addNext(node8); // node6.addNext(node7); // node7.addNext(node11); // node8.addNext(node9); // node9.addNext(node8); node9.addNext(node10); // node10.addNext(node5); node10.addNext(node12); // node11.addNext(node12); //初期化前必经节点的列表 for (int i = 0; i < nodeList.size(); i++) { nodeList.get(i).dominatorList.addAll(nodeList); } return nodeList; } }
打印结果如下:
迭代次数:1
迭代次数:2
*******************
node1
------
1
*******************
node2
------
1,2
*******************
node3
------
1,2,3
*******************
node4
------
1,2,4
*******************
node5
------
1,2,4,5
*******************
node6
------
1,2,4,6
*******************
node7
------
1,2,4,7
*******************
node8
------
1,2,4,5,8
*******************
node9
------
1,2,4,5,8,9
*******************
node10
------
1,2,4,5,8,9,10
*******************
node11
------
1,2,4,7,11
*******************
node12
------
1,2,4,12
相关文章推荐
- 计算流图中的前必经节点
- 表达式的计算结果必须为节点集 调试
- 邻接矩阵计算节点对最短路径
- Leetcode637. BFS计算二叉树每层节点的平均值
- packstack + vxlan 利用vbox虚拟机搭建1控制节点+2计算节点openstack
- 表达式的计算结果必须为节点集。
- 计算节点宕机了怎么办?- 每天5分钟玩转 OpenStack(43)
- 理解openstack中与虚拟机相关一些简单网络知识-3.计算节点的网络拓扑以及网络分配
- 一个tenant,两个网络,一个路由器 计算节点和网络节点配置
- 超千个节点OpenStack私有云案例(1):CERN 5000+ 计算节点私有云
- C++计算二叉树的节点数和高度
- 字段计算器计算面的节点数
- 树状结构的节点深度计算的sql
- Openstack 问题总结之:计算节点上网络访问慢的解决方法
- 节点的相关计算
- 数据结构——二叉树遍历、深度、叶子节点数计算
- openstack controller ha测试环境搭建记录(九)——配置nova(计算节点)
- 只使用指向二叉树的根的一个指针T,计算T中节点的个数,T中树叶的片数,T中满节点的个数
- Unity之计算子节点世界坐标
- TensorFlow 保存和导入计算图中的部分节点