Lutz Roeder 4 лет назад
Родитель
Сommit
a081bf8bc4
1 измененных файлов с 36 добавлено и 33 удалено
  1. 36 33
      source/dagre.js

+ 36 - 33
source/dagre.js

@@ -394,56 +394,59 @@ dagre.layout = (graph, options) => {
                 };
                 // Initializes cut values for all edges in the tree.
                 const initCutValues = (t, g) => {
-                    // Given the tight tree, its graph, and a child in the graph calculate and
-                    // return the cut value for the edge between the child and its parent.
-                    const calcCutValue = (t, g, child) => {
-                        const childLabel = t.node(child).label;
+                    const vs = [];
+                    const visited = new Set();
+                    const stack = [ Array.from(t.nodes.keys()).reverse() ];
+                    while (stack.length > 0) {
+                        const current = stack[stack.length - 1];
+                        if (Array.isArray(current)) {
+                            const v = current.pop();
+                            if (current.length === 0) {
+                                stack.pop();
+                            }
+                            if (!visited.has(v)) {
+                                visited.add(v);
+                                const children = t.neighbors(v);
+                                if (children.length > 0) {
+                                    stack.push(v);
+                                    stack.push(children.reverse());
+                                }
+                                else {
+                                    vs.push(v);
+                                }
+                            }
+                        }
+                        else {
+                            vs.push(stack.pop());
+                        }
+                    }
+                    for (const v of vs.slice(0, vs.length - 1)) {
+                        // Given the tight tree, its graph, and a child in the graph calculate and
+                        // return the cut value for the edge between the child and its parent.
+                        const childLabel = t.node(v).label;
                         const parent = childLabel.parent;
                         // The graph's view of the tree edge we're inspecting
-                        const edge = g.edge(child, parent);
+                        const edge = g.edge(v, parent);
                         // True if the child is on the tail end of the edge in the directed graph
                         const childIsTail = edge ? true : false;
                         // The accumulated cut value for the edge between this node and its parent
-                        const graphEdge = edge ? edge.label : g.edge(parent, child).label;
+                        const graphEdge = edge ? edge.label : g.edge(parent, v).label;
                         let cutValue = graphEdge.weight;
-                        const node = g.node(child);
+                        const node = g.node(v);
                         for (const e of node.in.concat(node.out)) {
-                            const isOutEdge = e.v === child;
+                            const isOutEdge = e.v === v;
                             const other = isOutEdge ? e.w : e.v;
                             if (other !== parent) {
                                 const pointsToHead = isOutEdge === childIsTail;
                                 cutValue += pointsToHead ? e.label.weight : -e.label.weight;
-                                const edge = t.edge(child, other);
+                                const edge = t.edge(v, other);
                                 if (edge) {
                                     const otherCutValue = edge.label.cutvalue;
                                     cutValue += pointsToHead ? -otherCutValue : otherCutValue;
                                 }
                             }
                         }
-                        return cutValue;
-                    };
-                    const postorder = (g, vs) => {
-                        const visited = new Set();
-                        const result = [];
-                        const dfs = (v) => {
-                            if (!visited.has(v)) {
-                                visited.add(v);
-                                for (const w of g.neighbors(v)) {
-                                    dfs(w);
-                                }
-                                result.push(v);
-                            }
-                        };
-                        for (const v of vs) {
-                            dfs(v);
-                        }
-                        return result;
-                    };
-                    const vs = postorder(t, Array.from(t.nodes.keys()));
-                    for (const v of vs.slice(0, vs.length - 1)) {
-                        const childLabel = t.node(v).label;
-                        const parent = childLabel.parent;
-                        t.edge(v, parent).label.cutvalue = calcCutValue(t, g, v);
+                        t.edge(v, parent).label.cutvalue = cutValue;
                     }
                 };
                 const leaveEdge = (tree) => {