计算流图中的前必经节点

来源:互联网 发布:js数组 key push 编辑:程序博客网 时间:2024/04/30 03:39

《现代编译器的Java实现》中的一图,左边是流图,右边是必经节点树

根据必经节点的算法写了程序验证了下。

只是为了验证算法,并没有考虑最优算法,不过因为此流图足够简单,所以只迭代了两次即求出了结果。

代码如下:

Node类抽象图中的节点,Dominator类用来计算

复制代码
 1 import java.util.ArrayList; 2 import java.util.List; 3  4 public class Node { 5     // 序号 6     public int no; 7     // 后接节点列表 8     public List<Node> nextList = new ArrayList<Node>(); 9     // 前接节点列表10     public List<Node> preList = new ArrayList<Node>();11     // 初始前必经节点(全体节点)12     public List<Node> dominatorList = new ArrayList<Node>();13 14     public Node(int no) {15         this.no = no;16     }17 18     public void addNext(Node n){19         nextList.add(n);20         n.preList.add(this);21     }22     23     public String toString(){24         return no+"";25     }26 }
复制代码
复制代码
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

0 0
原创粉丝点击